Spring4.x官方参考文档中文版——第21章 Web MVC框架(23)

21.10 Spring的multipart (多部件)(文件上传)支持

21.10.1 介绍

       Spring内置的multipart(多部件)支持,可以在web应用中处理文件的上传。你能够启用MultipartResolver(多部件解析器)对象来开启对多部件的支持功能。这个对象是在org.springframework.web.multipart包里定义的。Spring提供了基于Commons FileUpload的MultipartResolver的实现,也提供了基于Servlet3.0 多部件请求解析的MultipartResolver的实现。

       默认情况下,Spring是不会去处理多部件的,因为有些开发者想要自行处理它们。你可以在web应用中的context里,添加一个multipartresolver(多部件解析器)来启用Spring的多部件处理。每一个请求会被检测是否带有一个多部件。如果没有,那么请求照常处理,如果有多部件,在context中声明的MultipartResolver就会被使用。然后,在请求中的多部件就会被其处理。

21.10.2 使用基于Commons FileUpload的MultipartResolver(多部件解析器)

       下面的例子展示了如何使用CommonsMultipartResolver:

<bean id="multipartResolver"
       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 
    <!—其中一个property(属性)已经生效了; 即最大文件字节数 -->
    <property name="maxUploadSize" value="100000"/>
 
</bean>

       当然,你也需要在你的classpath下面放入对应的jar包,这样多部件解析器才能正常运行。在使用CommonsMultipartResolver时,你需要使用commons-fileupload.jar包。

       当Spring的DispatcherServlet检测到一个含有多部件的请求时,它会启用已经在context中声明了的解析器来处理这个请求。然后,这个解析器将会把现有HttpServletRequest封装成一个MultipartHttpServletRequest,以支持多部件文件上传。你能够获取到这个请求中所包含多部件的信息,也能在controller中访问到这个多部件文件。

 

21.10.3 使用基于Servlet3.0的MultipartResolver(多部件解析器)

       为了使用基于Servlet3.0的多部件解析,你需要在web.xml中的DispatherServlet上的”multipart-config”上进行标记,或者在javax.servlet.MultipartConfigElement

中使用编程式Servlet注册方式来启用。又或者,在你自己定义的Servlet类中,使用javax.servlet.annotation.MultipartConfig注解来启用它。类似于最大文件大小,储存位置之类的配置,需要在其中进行设置,在Servlet3.0这种级别的servlet的注册方式中,是不允许在MultipartResolver里进行设置的。

       当已经使用任意一种方式启用了Servlet3.0的多部件解析后,你就能在Spring的配置中添加StandarServletMultipartResolver了:

<bean id="multipartResolver"
       class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</bean>

21.10.4 在表单中处理文件上传

       在MultipartResolver完成了它的工作后,对于请求的处理就跟其他普通的请求一样了。首先,创建一个允许用户上传文件的表单,编码属性(enctype=”multipart/form-data”)可以让浏览器知道怎么去编码一个作为multipart(多部件)请求的表单:

<html>
    <head>
       <title>Upload a file please</title>
    </head>
    <body>
       <h1>Please upload a file</h1>
       <form method="post" action="/form" enctype="multipart/form-data">
           <input type="text" name="name"/>
           <input type="file" name="file"/>
           <input type="submit"/>
       </form>
    </body>
</html>

       下一步,是创建一个处理这个文件上传的controller,这个controller与普通的注解式@Controller是很相似的,不同的地方,只是在方法的参数中,使用了multipartHttpServletRequest或者MultipartFile:

@Controller
public classFileUploadController {
 
    @RequestMapping(path= "/form", method = RequestMethod.POST)
    public StringhandleFormUpload(@RequestParam("name") String name,
           @RequestParam("file") MultipartFile file){
 
       if (!file.isEmpty()) {
           byte[] bytes = file.getBytes();
           // 把这些字节存入某处
           return "redirect:uploadSuccess";
       }
 
       return "redirect:uploadFailure";
   }
 
}

        请注意看@RequestParam是怎样与表单中声明的输入元素进行关联映射的,在这个例子中,byte[]什么都没有做,但是,实战中你能把这个字节存入到数据库,存到硬盘中等等,都可以。

        当使用Servlet3.0的多部件解析,你也可以为方法参数使用javax.servlet.http.Part:

@Controller
public classFileUploadController {
 
    @RequestMapping(path= "/form", method = RequestMethod.POST)
    public StringhandleFormUpload(@RequestParam("name") String name,
           @RequestParam("file") Part file) {
 
       InputStream inputStream = file.getInputStream();
       // 把上传的文件字节存入某处
 
       return "redirect:uploadSuccess";
   }
 
}

21.10.5 在编程式客户端中处理文件上传请求

       多部件的请求也能在RESTful服务场景中的非浏览器客户端中进行上交。上面的所有例子和配置也能在此施行。然而,不像浏览器那样,一般来说就是上传文件和简单的表单字段,编程式的客户端可以在特定content type报头下传送更复杂的数据,比如一个带有文件,并在第二部分是JSON格式化的数据的多部件请求,如下:

POST/someUrl

Content-Type:multipart/mixed

 

--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp

Content-Disposition:form-data; name="meta-data"

Content-Type:application/json; charset=UTF-8

Content-Transfer-Encoding:8bit

 

{

       "name": "value"

}

--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp

Content-Disposition:form-data; name="file-data"; filename="file.properties"

Content-Type:text/xml

Content-Transfer-Encoding:8bit

... FileData ...

 

       你可以使用@RequestParam(“meta-data”)String metadata的controller方法入参,来访问名为”meta-data”的部分。然而,你可能更希望从请求的主体部分中,把JSON格式化的数据初始化成强类型的对象。

       你能够使用@RequestPart注解,替代@RequestParam注解来达到这个目的,它允许你拥有特定多部件的内容,并通过HttpMessageConverter来转换成”Content-Type”报头里理想的多部件对象。

@RequestMapping(path = "/someUrl", method = RequestMethod.POST)
public String onSubmit(@RequestPart("meta-data") MetaData metadata,
        @RequestPart("file-data") MultipartFile file) {
 
    // ...
 
}

        请注意看MultipartFile方法入参是怎样用@RequestParam(或者用@RequestPart互换)来进行访问的。然而, @RequestPart(“meta-data”) MetaData方法入参,在这种条件下,会根据他的”Content_Type”报头,读取成JSON内容,并在MappingJackson2HttpMessageConverter的帮助下,转换成JSON。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值