以前使用表单上传文件,需要用到 commons-fileupload组件,分为三步实现
相关类:
*工厂:DiskFileItemFactory
*解析器:ServletFileUpload
*表单项:FileItem
1)创建工厂:DiskFileItemFactoryfactory = new DiskFileItemFactory();
2)创建解析器:ServletFileUploadsfu = new ServletFileUpload(factory)
3)使用解析器来解析request,得到FileItem集合:
List<FileItem > fileItemList = sfu.parseRequest(requset);
其中FileItem中的方法:
*boolean isFormField():是否为普通表单项!返回true是普通,false是文件
*String getFieldName();返回当前表单项的名称
*String getString(String charset);返回表单项的值,参数是编码
*String getName();返回上传文件的名称
*long getSize();返回上传文件的字节数
*InputStream getInputStream();返回上传文件对应的输入流
*voidwrite(File destFile):把上传的文件内容保存到指定的文件中
============================================================================
对于Servlet3.0,现在可以使用Part接口加注解的形式,实现对表单数据的获取简单操作
对于多文件上传的处理:
<input name="smallImg" class="file-loading"type="file" multiple accept=".jpg,.jpeg,.png" data-min-file-count="1"data-show-preview="true">
<input name="smallImg" class="file-loading"type="file" multiple accept=".jpg,.jpeg,.png" data-min-file-count="1"data-show-preview="true">
<input name="smallImg" class="file-loading"type="file" multiple accept=".jpg,.jpeg,.png" data-min-file-count="1"data-show-preview="true">
对于上传的多个文件,我们可以通过Part接口来处理
在处理的Servlet需要申明这个Servlet是要接收大文件对象
@MultipartConfig// 申明这个Servlet是要接收大文件对象的
@WebServlet("/backStage")
public class BackStageServlet extends HttpServlet {
}
这里用到了两个标签@WebServlet和@MutipartConfig
@WebServlet用于将一个类声明为 Servlet,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为 Servlet。 ( 以下所有属性均为可选属性,但是 value、urlPatterns、servletNames 三者必需至少包含一个,且 value 和 urlPatterns 不能共存,如果同时指定,通常忽略 value 的取值 ):
属性名 | 类型 | 描述 |
---|---|---|
filterName | String | 指定过滤器的 name 属性,等价于 <filter-name> |
value | String[] | 该属性等价于 urlPatterns 属性。但是两者不应该同时使用。 |
urlPatterns | String[] | 指定一组过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。 |
servletNames | String[] | 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值,或者是 web.xml 中 <servlet-name> 的取值。 |
dispatcherTypes | DispatcherType | 指定过滤器的转发模式。具体取值包括: ASYNC、ERROR、FORWARD、INCLUDE、REQUEST。 |
initParams | WebInitParam[] | 指定一组过滤器初始化参数,等价于 <init-param> 标签。 |
asyncSupported | boolean | 声明过滤器是否支持异步操作模式,等价于 <async-supported> 标签。 |
description | String | 该过滤器的描述信息,等价于 <description> 标签。 |
displayName | String | 该过滤器的显示名,通常配合工具使用,等价于 <display-name> 标签。 |
@MutipartConfig该注解主要是为了辅助 Servlet 3.0 中 HttpServletRequest 提供的对上传文件的支持。该注解标注在 Servlet 上面,以表示该 Servlet 希望处理的请求的 MIME 类型是 multipart/form-data。另外,它还提供了若干属性用于简化对上传文件的处理。
属性名 | 类型 | 是否可选 | 描述 |
---|---|---|---|
fileSizeThreshold | int | 是 | 当数据量大于该值时,内容将被写入文件。 |
location | String | 是 | 存放生成的文件地址。 |
maxFileSize | long | 是 | 允许上传的文件最大值。默认值为 -1,表示没有限制。 |
maxRequestSize | long | 是 | 针对该 multipart/form-data 请求的最大数量,默认值为 -1,表示没有限制。 |
例如:
@MultipartConfig(fileSizeThreshold = 10000, maxFileSize = 1000000, maxRequestSize = 1000000, location="E:/logs")
============================================================================
这里我们就可以通过Part接口来获取多文件表单上传的文件
//接收文件表单项的名称List<String> imageList = new ArrayList<String>();//循环遍历获取表单项,提取其中文件表单,存入集合中for(Part part:request.getParts()){//request.getParts()获取的是所有表单项,这里我们只需要获得name为smallImg的即可if(part.getName().startsWith("smallImg")){//通过文件大小判断文件是否上传if(part.getSize() == 0){request.setAttribute("MSG3","图书图片未上传,请检查!");request.getRequestDispatcher("/WEB-INF/jsp/book_add.jsp").forward(request,response);return;}imageList.add(receiveImage(part));}
String receiveImage(Part part);这个方法的作用是将上传的文件保存到项目目录中,并且使用UUID随机命名,并且返回随机命名后的文件名
private String receiveImage(Part part) {try{//如果用户上传了这里代码是不会出现异常的//如果没有上传,这里出现异常//保存到项目的路径中去String sysPath = request.getSession().getServletContext().getRealPath("/img");//定义一个新的图片名称String fileName = UUID.randomUUID().toString();//提取图片后缀String contentDispostion = part.getHeader("content-disposition");// 获取上传文件的后缀名String suffix = contentDispostion.substring(contentDispostion.lastIndexOf("."), contentDispostion.length() - 1);fileName+=suffix;//把图片保存到项目路径中part.write(sysPath+"/"+fileName);return fileName;}catch (Exception e){e.printStackTrace();return null;}}
这样就可以通过将文件的名字保存到数据库中,并且在之后的显示界面通过项目路径显示对应的图片信息了
<img src="../../img/${book.imgPath}" class="img-responsive" alt=""/>