SpringMVC 处理multipart形式的数据

    multipart格式的数据会将一个表单拆分为多个部分(part),每个部分对应一个输入域。在一般的表单输入域中,它所对应的部分中会放置文本型数据,但是如果上传文件的话,它所对应的部分可以是二进制,下面展现了multipart的请求体:

    在这个multipart的请求中,可以看到profilePicture部分与其他部分明显不同。除了其他内容以外,它还有自己的Content-Type头,表明它是一个JPEG图片。

1.配置multipart解析器

    DispatcherServlet并没有实现任何解析multipart请求数据的功能。它将该任务委托给了Spring中MultipartResolver策略接口的实现,通过这个实现类来解析multipart请求中的内容。从Spring 3.1开始,Spring内置了两个MultipartResolver的实现供我们选择:

1.CommonsMultipartResolver:使用Jakarta CommonsFileUpload解析multipart请求;

2.StandardServletMultipartResolver:依赖于Servlet 3.0对multipart请求的支持(始于Spring 3.1)。

使用Servlet 3.0解析multipart请求

    其配置不在Spring中实现在servlet中实现。必须要指定在文件上传的过程中,所写入的临时文件路径。如果不设定这个最基本配置的话,StandardServlet-MultipartResolver就无法正常工作。必须要在web.xml或Servlet初始化类中,将multipart的具体细节作为DispatcherServlet配置的一部分。

    如果采用Servlet初始化类的方式来配置DispatcherServlet的话,这个初始化类应该已经实现了WebApplicationInitializer,那我们可以在Servlet registration上调用setMultipartConfig()方法,传入一个MultipartConfig-Element实例。如下是最基本的DispatcherServletmultipart配置,它将临时路径设置为“/tmp/spittr/uploads”


    如果配置DispatcherServlet的Servlet初始化类继承了AbstractAnnotationConfigDispatcherServletInitializer或AbstractDispatcher-ServletInitializer的话,那么我们不会直接创建DispatcherServlet实例并将其注册到Servlet上下文中。(不会得到DynamicServlet registration的引用)但是,我们可以通过重载customizeRegistration()方法(它会得到一个Dynamic作为参数)来配置multipart的具体细节:

除了临时路径的位置,其他的构造器所能接受的参数如下:
    1.上传文件的最大容量(以字节为单位)。默认是没有限制的。
    2.整个multipart请求的最大容量(以字节为单位),不会关心有多少个part以及每个part的大小。默认是没有限制的。
    3.在上传的过程中,如果文件大小达到了一个指定最大容量(以字节为单位),将会写入到临时文件路径中。默认值为0,也就是所有上传的文件都会写入到磁盘上。

假设我们想限制文件的大小不超过2MB,整个请求不超过4MB,而且所有的文件都要写到磁盘中。

用web.xml配置


<multipart-config>的默认值与MultipartConfigElement相同。与MultipartConfigElement一样,必须要配置的是<location>。

配置Jakarta Commons FileUpload multipart解析器

将CommonsMultipartResolver声明为Spring bean的最简单方式如下:

CommonsMultipart-Resolver不会强制要求设置临时文件路径。默认情况下,这个路径就是Servlet容器的临时目录。通过设置uploadTempDir属性,我们可以将其指定为一个不同的位置:

用CommonsMultipartResolver配置上面的列子

2.处理multipart请求

处理multipart请求最常见的方式就是在某个控制器方法参数上添加@RequestPart注解。

下面举个例子:

    <form>标签将enctype属性设置为multipart/form-data,这会告诉浏览器以multipart数据的形式提交表单,而不是以表单数据的形式进行提交。在multipart中,每个输入域都会对应一个part。除了注册表单中已有的输入域还添加了一个新的<input>域,其type为file。这能够让用户选择要上传的图片文件。accept属性用来将文件类型限制为JPEG、PNG以及GIF图片。根据其name属性,图片数据将会发送到multipart请求中的profilePicturepart之中。

获取图片方式一:

    当注册表单提交的时候,profilePicture属性将会给定一个byte数组,这个数组中包含了请求中对应part的数据(通过@RequestPart指定)。如果用户提交表单的时候没有选择文件,那么这个数组会是空(而不是null)。获取到图片数据后,processRegistration()方法剩下的任务就是将文件保存到某个位置。

方式二接受MultipartFile:(常用)

MultipartFile接口用来处理上传文件

MultipartFile提供了获取上传文件byte的方式,还能获得原始的文件名、大小以及内容类型。它还提供了一个InputStream,用来将文件数据以流的方式进行读取。还提供了一个便利的transferTo()方法,它能够帮助我们将上传的文件写入到文件系统中。

将文件保存到Amazon S3中

以Part的形式接受上传的文件

    如果你需要将应用部署到Servlet 3.0的容器中,那么会有MultipartFile的一个替代方案。Spring MVC也能接受javax.servlet.http.Part为控制器方法的参数。如果使用Part来替换MultipartFile的话,那么processRegistration()的方法签名将会变成如下的形式:



    如果在编写控制器方法的时候,通过Part参数的形式接受文件上传,那么就没有必要配置MultipartResolver了。只有使用MultipartFile的时候,我们才需要MultipartResolver。


参考《Spring实战》

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值