Multipart Resolver来自org.springframework.web.multipart包下的MultipartResolver提供解析包括文件上传在内的多部分请求策略。一种实现方式
Multipart Resolver
来自org.springframework.web.multipart
包下的MultipartResolver
提供解析包括文件上传在内的多部分请求策略。一种实现方式是基于Commons FileUpload
,另外则基于Servlet 3.0
的多部分请求解析。
启用多部分处理,需要在DispatcherServlet
Spring配置中声明一个名为multipartResolver
的MultipartResolver
bean。DispatcherServlet
检测到它并将其应用于传入的请求。当接收到一个content-type
是multipart/form-data
的POST请求时,解析程序将解析内容并将当前HttpServletRequest
包装为MultipartHttpServletRequest
,以提供对已解析部分的访问权限,此外将其作为请求参数公开。
Apache Commons FileUpload
使用Apache Commons FileUpload
,需要配置名称为multipartResolver
的CommonsMultipartResolver
类型的Bean。 还需要引入commons-fileupload
的依赖。
Servlet 3.0
启用Servlet 3.0多部分解析需要通过Servlet容器配置。操作如下:
- 通过Java配置, 在Servlet注册器中设置一个
MultipartConfigElement
。 - 通过web.xml, 在servlet定义中添加
<multipart-config>
部分。
代码实现
Spring MVC环境配置
通过MAVEN构建一个maven-archetypeweb-app
项目,通过Java代码形式配置SpringMVC,具体配置方式如下。
pom.xml,引入依赖
<properties> ... <spring.version>5.2.2.RELEASE</spring.version> <tomcat.version>8.5.5</tomcat.version></properties><dependencies> <!--spring -core--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!--web--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency></dependencies>
Spring MVC配置
AppConfig.java
@Configuration@ComponentScan("io.github.nirvanafire")public class AppConfig implements WebMvcConfigurer { ...}
MyWebApplicationInitializer.java
public class MyWebApplicationInitializer implements WebApplicationInitializer { private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024; @Override public void onStartup(ServletContext servletContext) throws ServletException { System.out.println("---MyApplicationInitializer onStartup---"); // 加载Spring Web应用配置 AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext (); ac.register(AppConfig.class); ac.refresh(); // 创建并注册DispatcherServlet(前端控制器) DispatcherServlet ds = new DispatcherServlet(ac); ServletRegistration.Dynamic registration = servletContext.addServlet("dispatchServlet", ds); registration.setLoadOnStartup(1); registration.addMapping("*.do"); }}
文件上传Controller实现
@RestControllerpublic class UploadController { @PostMapping("/upload_commons") public String uploadCommons(@RequestPart("file") MultipartFile file) { System.out.println("---Run Upload Commons---"); storeFile(file); return "success"; } private void storeFile(MultipartFile file) { try { String originalFilename = file.getOriginalFilename(); System.out.println("----File Name: " + originalFilename + "----"); File tmpFolder = new File("tmp"); if (!tmpFolder.exists()) { tmpFolder.mkdir(); } File tmp = new File("tmp/" + originalFilename); FileOutputStream fos = new FileOutputStream(tmp); FileCopyUtils.copy(file.getInputStream(), fos); } catch (IOException e) { System.out.println("Upload File Error: " + e.getMessage()); } }}
页面代码
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>SpringMVC-UploadFile</title></head><body> <h1>SpringMVC-UploadFile</h1> <hr> <h2>Apache Commons FileUpload</h2> <form action="/upload_commons.do" enctype="multipart/form-data" method="post"> <input type="file" name="file"> <input type="submit" value="Submit"> </form> </body></html>
Apache Commons FileUpload
在pom.xml文件中引入依赖Apache Commons FileUpload依赖:
<!-- commons-fileupload --><dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version></dependency>
在AppConfig.java
中声明一个名称为multipartResolver
的CommonsMultipartResolver
Bean。
@Configuration@ComponentScan("io.github.nirvanafire")public class AppConfig implements WebMvcConfigurer { ... @Bean("multipartResolver") public CommonsMultipartResolver commonsMultipartResolver() { CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(); return commonsMultipartResolver; }}
Servlet 3.0
在Servlet注册器中设置一个MultipartConfigElement
,即在MyWebApplicationInitializer.java
中添加如下代码:
private int MAX_UPLOAD_SIZE = 5 * 1024 * 1024;@Overridepublic void onStartup(ServletContext servletContext) throws ServletException { ... System.out.println("---tmpdir: " + System.getProperty("java.io.tmpdir") + "---"); File uploadDirectory = new File(System.getProperty("java.io.tmpdir")); /** * MultipartConfigElement参数含义 * @param location the directory location where files will be stored (上传文件存储目录) * @param maxFileSize the maximum size allowed for uploaded files(单文件上传大小限制) * @param maxRequestSize the maximum size allowed for multipart/form-data requests(一个请求上传大小限制) * @param fileSizeThreshold the size threshold after which files will (文件写入磁盘的阈值,可理解为每次读取文件大小) */ MultipartConfigElement multipartConfigElement = new MultipartConfigElement(uploadDirectory.getAbsolutePath(), MAX_UPLOAD_SIZE, MAX_UPLOAD_SIZE * 2, MAX_UPLOAD_SIZE / 2); registration.setMultipartConfig(multipartConfigElement);}
在AppConfig.java
中声明一个名称为multipartResolver
的StandardServletMultipartResolver
Bean。
@Configuration@ComponentScan("io.github.nirvanafire")public class AppConfig implements WebMvcConfigurer { ... @Bean("multipartResolver") public StandardServletMultipartResolver standardServletMultipartResolver() { StandardServletMultipartResolver standardServletMultipartResolver = new StandardServletMultipartResolver(); return standardServletMultipartResolver; }}
小结
不论是FileUpload
或是Servlet 3.0
实现多部分解析功能,都需要在DispatcherServlet
Spring配置中声明一个名为multipartResolver
的MultipartResolver
bean(FileUpload
声明CommonsMultipartResolver
,Servlet 3.0
声明StandardMultipartResolver
),通过限定声明bean的名称(multipartResolver
),限制项目中多部分解析仅有一种实现方式
相关链接
.
- 0