0
点赞
收藏
分享

微信扫一扫

简简单单-在Spring MVC中使用FileUpload功能


简简单单-在Spring MVC中使用FileUpload功能


博客分类:


  •  
  • Spring

Spring MVC Web JSP 工作 



  先让我们来看一段摘自《Spring 2.5 Reference 中文版》( http://www.redsaga.com/spring_ref/2.5/spring-reference.pdf)的一段关于FileUpload的开场描述: 
  "Spring支持web应用中的分段文件上传。这种支持是由即插即用的MultipartResolver来实现。这些解析器都定义在org.springframework.web.multipart包里。Sprig提供了现成的MultipartResolver可以支持Commons FileUpload( http://jakarta.apache.org/commons/fileupload)和COS FileUpload( http://www.servlets.ocm/cos)。" 

是的,Spring通过配置一个分段上传解析器来完成对文件上传的解析和封装工作,那么Spring是如何完成这一工作的呢: 

首先,DispatcherServlet必须找到一个文件上传解析器的实例,使用这个实例来检查本次请求的HttpServletRequest是否是一个分段文件上传的Request,通过下面的Spring 源码可以看到,首先必须保证有一个MultipartResolver的实例,并且由该类的Resolver的isMultipart方法来验证,本次Request是否为文件上传的Request.如果以上条件都满足,那么Spring将其转换为一个继承自HttpServletRequest的MultipartHttpServletRequest返回,这样在你的Controller中就可以使用这个经过转换的request,从中取到MultipartFile信息。 

Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml




1. protected HttpServletRequest checkMultipart(HttpServletRequest request) throws
2. if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {  
3. if (request instanceof
4. "Request is already a MultipartHttpServletRequest - if not in a forward, "
5. "this typically results from an additional MultipartFilter in web.xml");  
6.         }  
7. else
8. return this.multipartResolver.resolveMultipart(request);  
9.         }  
10.     }  
11. // If not returned before: return original request.
12. return
13. }



由以上分析可以看出,我们必须配置一个MultipartResolver,在这里我们使用支持Commons FileUpload的CommonsMultipartResolver: 


Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml


1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"/>


而且我们可以在该Resolver中定义文件上传的最大长度: 


Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml

1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8" p:maxUploadSize="100000"/>


当用户选择的上传文件大于maxUploadSize值的时候,commons fileupload会抛出一个异常MaxUploadSizeExceededException表示用户上传的文件超出了最大限制。 



当然,我们可以通过Spring MVC中的ExceptionResolver来针对该异常定义一个显示错误的View,但针对有可能存在的多个文件上传Controller中都会发生文件大小超长这个异常的情况,除了我们自定义一个粒度更细的ExceptionResolver,我们还可以把上传文件合法性判断挪到用户自己的Controller中来做。而且我个人更偏向于后一种做法。 



除了Spring Configuration之外,我们还需要准备一个页面上传的jsp文件供View视图使用: 


Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml


1. <%@ page language="java" contentType="text/html; charset=UTF-8"
2. "UTF-8"%>  
3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
4.   
5. <html>  
6.     <head>  
7. "Content-Type" content="text/html; charset=UTF-8">  
8.         <title>Insert title here</title>  
9.     </head>  
10.       
11. "text-align:left">  
12. if(request.getAttribute("success") != null) {%>  
13.             Upload Successfully!!!<br/>  
14.         <% }%>  
15. "loginform" name="loginform" method="POST" enctype="multipart/form-data">  
16. "100%" border="0" cellspacing="0" cellpadding="0">  
17.                 <tr>  
18. "30" align="right">Choose File</td>  
19. "left">  
20. "imageFile" type="file"/>  
21.                     </td>  
22.                 </tr>  
23.                 <tr>  
24. "center" colspan="2">  
25. "submit" value="submit" name="submit"
26.                     </td>  
27.                 </tr>  
28.             </table>  
29.         </form>  
30.     </body>  
31. </html>


注意:在文件上传Form表单中,一定要将enctype设置为"multipart/form-data"因为只有这样才能使Spring知道这是一个文件上传的请求。 



细心的读者也许能发现Form表单中action为默认值也就是说post到和上传页面同样的URL,因此我们定义了一个Controller分别来处理这个请求的GET和POST请求。下面让我们来看看这个Controller: 



1.我们通过@Controller声明这个类为Spring组件,告知Spring容器在初始化的时候需要加载该类实例到Spring Context Container中。 


2.通过@RequestMapping("/sec_upload.do")将sec_upload.do的请求指向该Controller处理。 


Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



    1. @Controller
    2. @RequestMapping("/sec_upload.do")  
    3. public class
    4. //...
    5. }


    3.定义一个处理GET请求的方法,该方法简单的将选择文件Form表单页展现给用户: 


    Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml


    1. @RequestMapping(method = RequestMethod.GET)  
    2. public
    3. return "uploadView";  
    4.     }


    4.定义一个处理POST请求的方法,该方法进行用户文件上传处理: 


    Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



    1. @RequestMapping(method = RequestMethod.POST)  
    2. public
    3. @RequestParam("imageFile") MultipartFile file, Model model)  
    4. throws
    5. //具体的业务逻辑操作。。。
    6. "success", "true");  
    7. return "uploadView";  
    8.     }


    通过@RequestParam("imageFile")注解,Spring会将request请求中的imageFile的文件信息自动绑定到MultipartFile对象。 



    上面的Controller方法解决的文件绑定的问题,但假设我们的Form表单中除了文件选择框还有其他一些用户填写的信息,那么我们怎么处理呢?仿照上面的方法,我们可以为多个参数提供多个@RequestParam注解来完成数据绑定工作,但我们也可以通过MultipartHttpServletRequest对象来获取这些信息,因为在DispatcherServlet中Spring已经将一个普通的HttpServletRequest转换为了一个MultipartHttpServletRequest: 


    Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



      1. @RequestMapping(method = RequestMethod.POST)  
      2. public
      3. throws
      4. "imageFile");  
      5. //request.getParameter("xxx");
      6. //request.getContentType();
      7. //request.getContentLength();
      8. //some other processing...
      9. "success", "true");  
      10. return "uploadView";  
      11. }




      这种方式还是需要我们不断的通过request.getParameter("xxx")方式来获得参数,了解Spring MVC的同学可能想到了,使用CommandObject绑定-回答正确。假设我们定义了一个POJO对象: 


      Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



        1. public class
        2. private
        3.   
        4. public
        5. return
        6.     }  
        7.   
        8. public void
        9. this.imageFile = imageFile;  
        10.     }  
        11.   
        12. private
        13.   
        14. public
        15. return
        16.     }  
        17.   
        18. public void
        19. this.name = name;  
        20.     }  
        21. }



        这个对象中不仅包括需要封装的上传文件信息,还包括其他一些用户输入的普通信息。那么有了这个封装对象,我们的Controller可以变成如下的样子: 


        Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



          1. @RequestMapping(method = RequestMethod.POST)  
          2. public String handleThirdUploadProcess(BoUploadFile uploadFile, Model model) throws
          3.     MultipartFile file = uploadFile.getImageFile();  
          4. //这里你可以通过uploadFile.getName()...等等获取用户输入的其他普通信息了。
          5. "success", "true");  
          6. return "uploadView";  
          7. }




          5.自定义一个文件验证类,来验证文件的合法性。 


          Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml


          1. /**
          2.  * 用户文件上传验证类
          3.  * 
          4.  * @author Jacky Lau created at 2008-8-27
          5.  * @since 1.0
          6.  * @version 1.0
          7.  */
          8. public class
          9.   
          10. private final static long MAX_SIZE = 1024 * 1024;  
          11.   
          12. /**
          13.      * 文件大小上限
          14.      */
          15. private long
          16.   
          17. /**
          18.      * 可接受的文件content-type
          19.      */
          20. private
          21.   
          22. @PostConstruct
          23. public void
          24.         Assert  
          25.                 .notEmpty(allowedContentTypes,  
          26. "The content types allowed to be uploaded must contain one at least!");  
          27.     }  
          28.   
          29. /**
          30.      * 验证上传文件是否合法,如果不合法那么会抛出异常
          31.      * 
          32.      * @param file
          33.      *            用户上传的文件封装类
          34.      */
          35. public void
          36. "The multipart file is null!");  
          37. if
          38. throw new FileOutOfMaxLengthException("error.upload.outmaxlen",  
          39. new
          40. "The file uploaded is out of max file size!");  
          41. if
          42. throw new ContentTypeNotSupportException("error.upload.content.notsupported", null,  
          43. "The content type '"+file .getContentType()+"' is not a valid content type !");  
          44.     }  
          45.   
          46. /**
          47.      * 设置文件上传大小上限
          48.      * 
          49.      * @param maxSize
          50.      *            文件上传大小上限
          51.      */
          52. public void setMaxSize(long
          53. this.maxSize = maxSize;  
          54.     }  
          55.   
          56. /**
          57.      * 设置可接受的文件content-type数组
          58.      * 
          59.      * @param allowedContentTypes
          60.      *            可接受的文件content-type数组
          61.      */
          62. public void
          63. this.allowedContentTypes = allowedContentTypes;  
          64.     }  
          65.   
          66. }




          这样我们可以通过这个validator判断上传的文件是否超出了最大限制,文件格式是否正确等判断。我们可以通过配置文件配置该验证器,在这里为了方便起见在类中我用以下方式来初始化该验证器: 


          Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



            1. private
            2.   
            3. @PostConstruct
            4. public void
            5. new
            6. new String[] { "image/jpeg",  
            7. "image/pjpeg"
            8. }



            至此,我们已经完成了文件上传的开发,可以看出这和普通的Controller开发没有任何区别,简单而且灵活。以下是该Controller的全部代码: 



            Java代码   简简单单-在Spring MVC中使用FileUpload功能_web.xml



              1. @Controller
              2. @RequestMapping("/sec_upload.do")  
              3. public class
              4.   
              5. private
              6.   
              7. @PostConstruct
              8. public void
              9. new
              10. new String[] { "image/jpeg",  
              11. "image/pjpeg"
              12.     }  
              13.   
              14. @RequestMapping(method = RequestMethod.GET)  
              15. public
              16. return "uploadView";  
              17.     }  
              18.   
              19. @RequestMapping(method = RequestMethod.POST)  
              20. public
              21. @RequestParam("imageFile") MultipartFile file, Model model)  
              22. throws
              23.         validator.validate(file);  
              24. "d:\\temp\\ftp\\"
              25. "d:\\temp\\ftp\\resize\\"
              26.                 + file.getOriginalFilename();  
              27.         FileHelper.save(path, file.getBytes());  
              28. if
              29. 120, 118);  
              30. "success", "true");  
              31. return "uploadView";  
              32.     }  
              33. }



              在以后的文章中,我会对Spring进行上传文件特殊处理做一些探究,比如用户上传一个csv的通讯录文件,那么通过Spring的属性编辑器一个custom的Editor来进行数据转换,可以将CSV中的信息转换成其他你所需要的信息:比如从CSV文件中抽取邮件地址放到一个字符串数组中,让你可以进行后续的业务逻辑操作。。。 


              举报

              相关推荐

              0 条评论