springMVC之单文件上传

springmvc对form表单的支持已经很成熟,仅仅两步:

  1. 配置支持文件上传的bean:org.springframework.web.multipart.commons.CommonsMultipartResolver
    springMVC之单文件上传
      同时设置文件编码、单次提交表单上传文件最大字节数、以及写文件时使用的缓冲区大小
  2. 开发处理:handler[org.hy.ssm.web.controller.FormController.uploadOne(MultipartFile)]
     
    Java代码  springMVC之单文件上传
    1. /** 
    2.  * @Title: uploadOne 
    3.  * @Description: 单文件上传 
    4.  * @param file 
    5.  * @return ModelMap 
    6.  */  
    7. @RequestMapping("/uploadOne")  
    8. @ResponseBody  
    9. public ModelMap uploadOne(MultipartFile file) {  
    10.     final String UPLOAD_DIR = "/upload/";  
    11.     final String KEY_OF_ORIGINAL_FILE_NAME = "origFileName";  
    12.     final String KEY_OF_FILE_URL = "fileUrl";  
    13.     final String KEY_OF_FILE_SUFFIX = "fileSuffix";  
    14.   
    15.     boolean flag = false;  
    16.     String message = null;  
    17.     Map<String, String> data = Maps.newHashMap();  
    18.   
    19.     // 原文件名(通常用于下载展示)  
    20.     String originalFilename = file.getOriginalFilename();  
    21.     data.put(KEY_OF_ORIGINAL_FILE_NAME, originalFilename);  
    22.   
    23.     // 文件类型(后缀)  
    24.     String suffix = FileUtil.getSuffix(originalFilename);  
    25.     data.put(KEY_OF_FILE_SUFFIX, suffix);  
    26.   
    27.     // 目标文件名(通常情况需要重命名, 防止同名文件覆盖)  
    28.     String fileName = String.valueOf(System.currentTimeMillis()) + suffix;  
    29.     String fileUrl = (UPLOAD_DIR + fileName);  
    30.     data.put(KEY_OF_FILE_URL, fileUrl);  
    31.   
    32.     try {  
    33.         File dest = WebUtil.getFile(fileUrl);  
    34.         file.transferTo(dest);  
    35.         flag = true;  
    36.     } catch (Exception e) {  
    37.         flag = false;  
    38.         message = "";  
    39.         LOGGER.warn(message + " : " + e.getMessage(), e);  
    40.     }  
    41.   
    42.     return WebUtil.getModelMap(flag, data, message);  
    43. }  
     

接下来验证结果是否正确:
springMVC之单文件上传
 

  • 正常验证
    springMVC之单文件上传
     
    springMVC之单文件上传
     
  • 非法验证,文件大小超出。当前测试数据70+MB
    Java代码  springMVC之单文件上传
    1. org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 32505856 bytes exceeded; nested exception is org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (79882924) exceeds the configured maximum (32505856)  
    2.     at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:160)  
    3.     at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)  
    4.     at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1020)  
    5.     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:883)  
    6.     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)  
    7.     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)  
    8.     at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)  
    9.     at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)  
    10.     at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)  
    11.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)  
    12.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)  
    13.     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)  
    14.     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)  
    15.     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)  
    16.     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)  
    17.     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)  
    18.     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)  
    19.     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)  
    20.     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)  
    21.     at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)  
    22.     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)  
    23.     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)  
    24.     at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)  
    25.     at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)  
    26.     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)  
    27.     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)  
    28.     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)  
    29.     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)  
    30.     at java.lang.Thread.run(Thread.java:722)  
    31. Caused by: org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (79882924) exceeds the configured maximum (32505856)  
    32.     at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:937)  
    33.     at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)  
    34.     at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)  
    35.     at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)  
    36.     at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)  
    37.     ... 28 more  
     由错误也可定位出,#multipartResolver.maxUploadSize 是用来定位单次表单提交时,文件的限定大小

到此,单文件上传已经搞定。是不是很简单呢?当然了还有稍微原始的方法,通过 org.apache.commons.fileupload.servlet.ServletFileUpload 也能实现文件上传的功能,在此不做详解。大致步骤如下:

  1. 获取工厂 DiskFileItemFactory
  2. 通过工厂获取上传组件 ServletFileUpload
  3. 解析请求获取表单项
  4. 判断表单项类型
  5. 解析表单项
Java代码  springMVC之单文件上传
  1. /** 
  2.  * @Title: uploadByFileUpload 
  3.  * @Description: 使用Commons.FileUpload上传文件 
  4.  */  
  5. @RequestMapping("/uploadByFileUpload")  
  6. public void uploadByFileUpload() {  
  7.     final String UPLOAD_DIR = "upload/";  
  8.     final String basePath = WebUtil.getBaseFilPath();  
  9.   
  10.     HttpServletRequest request = WebUtil.getRequest();  
  11.     try {  
  12.         // 防止中文名乱码  
  13.         request.setCharacterEncoding("utf-8");  
  14.   
  15.         // 1. 获取工厂 DiskFileItemFactory  
  16.         DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();  
  17.         // 缓存区目录  
  18.         fileItemFactory.setRepository(new File(basePath + "tmp/"));  
  19.         // 缓存区大小  
  20.         fileItemFactory.setSizeThreshold(1024 * 6);  
  21.   
  22.         // 2. 通过工厂获取上传组件 ServletFileUpload  
  23.         ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);  
  24.         // 设置文件的大小为2M  
  25.         servletFileUpload.setSizeMax(1024 * 1024 * 2);  
  26.         // 防止中文乱码(文件名)  
  27.         servletFileUpload.setHeaderEncoding("UTF-8");  
  28.   
  29.         // 3. 解析请求获取表单项  
  30.         @SuppressWarnings("unchecked")  
  31.         List<FileItem> items = servletFileUpload.parseRequest(request);  
  32.   
  33.         // 4. 判断表单项类型  
  34.         for (FileItem item : items) {  
  35.   
  36.             // 5. 解析表单项  
  37.             // 表单项名称  
  38.             String fieldName = item.getFieldName();  
  39.             if (item.isFormField()) {  
  40.                 // 普通表单项处理  
  41.                 String name = fieldName;  
  42.                 String value = item.getString("UTF-8");  
  43.                 System.out.println(name + ":" + value);  
  44.   
  45.             } else {  
  46.                 // 文件表单项  
  47.                 // 获取文件名  
  48.                 String originalFileName = item.getName();  
  49.                 String suffix = FileUtil.getSuffix(originalFileName);  
  50.                 String newFileName = String.valueOf(System.currentTimeMillis());  
  51.   
  52.                 // 写入文件  
  53.                 String fileName = File.separator + newFileName + suffix;  
  54.                 File newFile = FileUtil.createQuietly(basePath + UPLOAD_DIR + fileName);  
  55.                 item.write(newFile);  
  56.                 item.delete();  
  57.             }  
  58.         }  
  59.   
  60.     } catch (Exception e) {  
  61.         LOGGER.warn(e.getMessage(), e);  
  62.     }  
  63. }  

注意:如果使用上面的方式获取上传文件,需要停止 springmvc 的文件解析机制,否则将不能获取数据 !!


springMVC之单文件上传
 

源码下载:ssmFU.zip