Spring MVC 处理 multipart 形式的数据

multipart格式的数据会将一个表单拆分成为多个部分,每个部分对应一个输入域

1. 配置multipart解析器

Spring中通过MultipartResolver接口的实现类来解析multipart请求中的内容,从Spring3.1开始,Spring内置了两个它的实现类:

  • CommonsMultipartResolver:使用Jakarta Comomons FileUpload 解析multipart请求
  • StandardServletMultipartResolver:依赖于Servlet3.0对multipart请求的支持

1.1 使用StandardServletMultipartResolver

没有构造器参数,也没要设置的属性

	@Bean
    public MultipartResolver multipartResolver() {
        return new StandardServletMultipartResolver();
    }

这里只是声明了StandardServletMultipartResolver,没有关于上传的任何配置,它的配置不在Spring中配置,而是在Servlet中指定。至少要指定文件上传过程中的写入的临时文件路径,否则无法正常工作。所以我们必须要在web.xml或Servlet初始化类中将multipart的具体细节作为DispatcherServlet配置的一部分

1.1.1 采用servlet初始化类的方式

DispatcherServlet ds = new DispatcherServlet ();
Dynamic registration = context.addServlet("appServlet", ds);
resistration.addMapping("/");
registration.setMultipartConfig(new MultipartConfigElement("/tmp/spitter/uploads"));

1.1.2 采用重载方法方式
如果我们采用的是继承AbstractAnnotationConfigDispatcherServletInitializerAbstractDispatcherServletInitializer的方法注册DispatcherServlet,那么我们就不会直接创建DispatcherServlet的实例并注册到Servlet上下文中,就不会有对Dynamic Servlet registration 的引用提供使用了:

	@Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
    	//设置上传文件的临时存储目录
        registration.setMultipartConfig(new MultipartConfigElement("/tmp/spitter/uploads"));
    }
  • MultipartConfigElement 的构造器参数
    1. 临时路径
    2. 上传文件的最大容量(字节),默认没有限制
    3. 整个multipart请求的最大容量(字节),默认没有限制
    4. 上传过程中,如果文件大小达到了一个指定的最大容量(字节),将会写入到临时文件路径中,默认值为0,也就是所有上传文件都会写入到磁盘上
      new MultipartConfigElement("/tmp/spitter/uploads", 2097152, 4194304, 0)
      限制文件大小不超过2MB,整个请求不超过4MB,所有文件写入磁盘中

1.1.3 采用web.xml方式

<servlet> <!--注册DispatcherServlet-->
	<servlet-name>dispatcher</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<load-on-startup>1</load-on-startup>
	<multipart-config>
		<location>/tmp/spitter/uploads</location> <!--location必须配置-->
		<max-file-size>2097152</max-file-size>
		<max-request-size>4194304</max-request-size>
	</multipart-config>
</servlet>

1.2 配置Jakarta Comomons FileUpload multipart 解析器
如果应用部署到非Servlet3.0容器中,就需要新的MultipartResolver实现,Spring内置了CommonsMultipartResolver

	@Bean
    public MultipartResolver multipartResolver() {
        return new CommonsMultipartResolver();
    }

CommonsMultipartResolver 不强制要求设置临时文件路径,默认是Servlet容器的临时目录
也可以手动设置:

	@Bean
    public MultipartResolver multipartResolver() {
    	CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    	multipartResolver.setUploadTempDir(new FileSystemResource("/tmp/spitter/uploads"));
    	multipartResolver.setMaxUploadSize(2097152);
    	multipartResolver.setMaxInMemorySize(0);
        return new CommonsMultipartResolver();
    }

这种方式无法设定multipart请求整体最大容量。

2. 处理multipart请求

2.1 接收MultipartFile

	@RequestMapping(value = "/register", method = RequestMethod.POST)
    public String register(@RequestPart("image") byte[] image,...) {
		...
	}

使用byte数组接收上传文件功能有限,Spring提供了MultipartFile接口

public interface MultipartFile {
    String getName();
    String getOriginalFilename();
    String getContentType();
    boolean isEmpty();
    long getSize();
    byte[] getBytes() throws IOException;
    InputStream getInputStream() throws IOException;
    void transferTo(File var1) throws IOException, IllegalStateException;
}
	@RequestMapping(value = "/register", method = RequestMethod.POST)
    public String register(@RequestPart("image") MultipartFile image,...) {
		...
		image.transferTo(new File("E:\\exec\\" + image.getOriginalFilename())); //保存文件
		...
	}

2.2 1
2.3 以Part形式接收上传文件

如果应用部署到Servlet3.0容器中,SpringMVC也能接受javax.servlet.http.Part作为控制器方法的参数

public interface Part {
    InputStream getInputStream() throws IOException;
    String getContentType();
    String getName();
    String getSubmittedFileName();
    long getSize();
    void write(String var1) throws IOException;
    void delete() throws IOException;
    String getHeader(String var1);
    Collection<String> getHeaders(String var1);
    Collection<String> getHeaderNames();
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
    public String register(@RequestPart("image") Part image,...) {
		...
		image.write("E:\\exec\\" + image.getSubmittedFileName());
		...
	}

接口方法基本相同
javax.servlet-api 的版本要在3.1以下的版本中没有getSubmittedFileName()方法,要注意可能项目引入的包是3.1以上的,但运行的容器中版本是3.1以下的,会报错NoSuchMethodError
如果以Part参数的形式接收文件上传,就没有必要配置MultipartResolver bean了,只有使用MultipartFile的时候才需要配置MultipartResolver
之前设置的new MultipartConfigElement("/tmp/spitter/uploads", 2097152, 4194304, 0)上传文件配置和这个MultipartResolver没关系,是所有上传文件的规范


  1. 212 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值