Spring_SpringMVC处理文件上传
世上最快乐的事,莫过于为理想而奋斗。—— 苏格拉底
1、multipart请求
一般表单提交所形成的请求结果时很简单的,就是以"&"符分割的多个name-value对,如:"firstName=Charles&lastName=Bob"。对于典型的基于文本的表单提交,这种编码形式也足够满足要求,但是对于multipart请求中传送二进制数据,就显得力不从心。
对于multipart请求,对于multipart格式的二进制数据会将一个表单拆分为多个部分(part),每个部分对应一个输入域。在一般的表单输入 域中它所对应的部分中会放置文本型数据,但是如果上传文件的话,它所对应的部分可以是二进制。
2、配置multipart解析器
从 Spring 3.1 开始,Spring 内置了两个 MultipartResolver 类的实现供我们选择:
1) CommonMultipartResolver:使用 Jakarta Commons FileUpload 解析 multipart 请求。
2)StandardServletMultipartResolver:依赖于 Servlet 3.0 对 multipart 请求的支持。
2.1 使用 Servlet 3.0 解析 multipart 请求(配置StandardServletMultipartResolver)
package com.spring.fileupload.config;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.servlet.DispatcherServlet;
public class FileUpLoadWebAppInitialzer implements WebApplicationInitializer{
public void onStartup(ServletContext servletContext) throws ServletException {
DispatcherServlet ds = new DispatcherServlet();
Dynamic registration = servletContext.addServlet("appServlet", ds);
registration.addMapping("/");
registration.setMultipartConfig(
new MultipartConfigElement("/temp/uploads"));
}
}2)如果我们配置 DispatcherServelt 的 Servlet 初始化类继承了 AbstractAnnotationConfigDispatcherServletInitilaizer 或
AbstractDispatcherServletInitializer 的话,我们可以通过重载 customizeRegistration() 方法来配置 multipart 的具体细节。
package com.spring.fileupload.config;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class FileUpLoadWebAppInitialzer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] { "/" };
}
@Override
protected void customizeRegistration(Dynamic registration) {
// TODO Auto-generated method stub
new MultipartConfigElement("/temp/uploads");
}
}3)除了指定上传文件的临时目录外,我们还可以通过其他的构造器来配置 multipart 的具体细节,如:
(1) 限定上传文件的最大容量(以字节为单位),默认是没有限制的。
(2)限定整个 multipart 请求的最大容量(以字节为单位),默认是没有限制的。
(3)在上传的过程中,如果文件达到指定大小(以字节为单位),将会写入到临时文件路径中,默认为0。
2.2 配置 Jakarta Commons FileUpload multipart 解析器
package com.spring.fileupload.config;
import java.io.IOException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
@ComponentScan("com.spring.fileupload")
public class WebConfig extends WebMvcConfigurerAdapter{
@Bean
public MultipartResolver multipartResolver() throws IOException {
CommonsMultipartResolver multipartResolver =
new CommonsMultipartResolver();
//设置临时目录路径
multipartResolver.setUploadTempDir(new FileSystemResource("/temp/uploads"));
//限定最大的文件容量为2MB
multipartResolver.setMaxUploadSize(2097152);
//限定最大的内存大小为0字节
multipartResolver.setMaxInMemorySize(0);
return multipartResolver;
}
}3、处理multipart请求
<!-- enctype属性设置告诉浏览器以multipart数据的形式提交表单 -->
<form action="/uploadImg" enctype="multipart/form-data">
<label>Upload Picture</label>
<!-- accept属性设置将上传文件类型限制为JPEG,PNG以及GIF图片 -->
<input type="file" name="picture" accept="image/jpeg,image/png,image/gif">
</form>当表单提交时,我们编写的控制器方法就会接受上传的文件数据。
@RequestMapping(value="/uploadImg")
public String uploadPicture(
@RequestPart("picture") byte[] picture
) {
return "success";
}