为DispatcherServlet添加文件上传支持

        对于一般的Servlet,我们可以在Servlet类上添加@MultipatConfig注解,使得该Servlet可以处理表单里涉及到文件上传。对应的那个表单,在其<form>元素也应该设置属性enctype,值为multipart/form-data。经过这两步的设置后,表单的各输入域都将封装为一个个的Part对象。但是只有在文件输入域对应的Part对象上调用getContenType方法返回的字符串才不为空。或者在已经知道文件输入域的name属性的情况下,直接调用HttpServletRequest.getPart(String name)方法,得到文件输入域抽象出来的Part对象。

        而SpringMVC提供的DispatcherServlet文件,使用者无法在源文件上编辑。为了使得这个Servlet能够支持文件上传,就必须要通过其他的途径。在AbstractAnnotationConfigDispatcherServletInitializer抽象类上有一个方法。

这个方法实际上来源于它的直接父类AbstractDispatcherServletInitializer。方法的参数列表传入的registration实际上是在ServletContext上调用addServlet(...)方法后的返回对象。对于SpringMVC来说,就是在ServletContext上添加DispatcherServlet后的返回对象。而这个对象有方法如下:

        可见,如果要为一个Servlet添加文件上传支持,就的在与这个Servlet关联的ServletRegistration.Dynamic对象上调用后者的setMutipartConfig方法。而对SpringMVC来说就是在AbstractAnnotationConfigDispatcherServletInitializer的实现类上重写customizeRegistration方法,在该方法内部调用方法参数registration的setMutipartConfig方法。

        setMutipartConfig方法仍然需要接受一个参数,这个参数是关于对上传文件的一些限制。以MutipartConfigElement的其中一个构造方法为例:

location参数设置要把这个上传上来的文件放在服务器的那个位置,这个位置是一个基础位置。maxFileSize设置单个文件最大大小,maxRequestSize设置上传上来所有文件的总和大小限制。

        因此,重写AbstractAnnotationConfigDispatcherServletInitializer的实现类的customizeRegistration方法,并在方法内部使用语句:registration.setMultipartConfig(new MutipartConfigElement("/date",10,100,0)),这样就设置好了DispatcherServlet对上传文件的支持,并且文件存放的基础路径是/WEB-INF/date,限制单个文件大小为10字节,限制所有文件的总大小为100字节。

        但是我们知道DispatcherServlet的定位是一个转发器,所以得到的文件应该交由具体的Controller处理,并且从文件输入域对应的Part对象中分离出有用的信息也不容易,所以通常还向Spring IoC容器注册一个bean:StandardServletMultipartResolver。在这之后,我们只需在被@RequestMapping注解的方法的参数列表上添加一个参数类型为MultipartFile的参数,并且用@RequestPart(..)注解这个参数,括号中的内容是一个字符串,这个字符串应当与表单中某一个的文件输入域的name属性一致。

        综上所述,如果不考虑缘由,要使得DispatcherServlet支持文件上传需要以下几步:

        1.在AbstractAnnotationConfigDispatcherServletInitializer的实现类中重写customizeRegistration方法:

注:使用MutipartConfigElement其他构造器可以进一步限制文件大小,同时“D:\\”路径是Windows路径。

        2.在DispatcherServlet持有的那个Spring IoC容器中配置一个Bean:

注:我采用的是Java配置类的方式来向Spring容器添加Bean,如果你使用的是XML方式,请在Spring容器配置文件中添加<bean>元素

        3.找到表单提交后映射到的处理方法,即@RequestMapping注解的方法,在起参数列表上添加参数


注:Multipart类型参数是我们要添加的参数,它需要被@RequestPart注解,字符串"filename1"这个值来源于表单中文件输入域的name属性

       4.之后就可以通过multipartFile引用操作了。通过调用multipart.transferTo(File file)方法,可以最终确定要把文件放在服务器的哪个位置,例如,如果是new File("resource\\"+multipartFile.getOriginalFilename())。那个将会在D:\resource下,文件的名称取决于multipartFile.getOriginalFilename()方法。因为是“\”是功能性的转义字符,所以需要两个“\”符号。路径“D:\resource”中的“D:\”来源于第1步的设置.

        5.如果上传文件的文件名含有中文,那么应该为DispatcherServlet添加过滤器。方式是在AbstractAnnotationConfigDispatcherServletInitializer的实现类中重写getServletFilters方法。过滤器中设置utf-8的字符编码。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容