Spring默认提供了文件上传的功能。用起来非常简单,我们也可以使用第三方的如Apache的CommonsUpload包来处理。这里我们使用Spring自带的解析。
基本用法
1、在Spring配置中,加上MultipartResolver接口的Bean。
@Bean(
name = {"multipartResolver"}
)
@ConditionalOnMissingBean({MultipartResolver.class})
public StandardServletMultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
2、前端表单类型method为POST方法,enctype为”multipart/form-data”
<form method="post" action="/form" enctype="multipart/form-data">
<input type="text" name="name"/>
<input type="file" name="file"/> <input type="submit"/>
</form>
3、Controller文件中写好相应的映射,上传文件的内容可以通过MultiPartFile来获取字节流并处理
@PostMapping("/form")
public String handleFormUpload(
@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) throws IOException {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes(); // store the bytes somewhere return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
原理
1、Spring的DispatchServlet可以检测到当前的请求是否为MultiPart请求。
![img_aafdb79560caa6c436965d465644bfa2.png](https://yqfile.alicdn.com/img_aafdb79560caa6c436965d465644bfa2.png?x-oss-process=image/resize,w_1400/format,webp)
DispatchServlet
2、如果检测为MultiPart请求,则去解析MultiPart请求
![img_541a6ff4ed79aff63f8a8e8c25a7d3af.png](https://yqfile.alicdn.com/img_541a6ff4ed79aff63f8a8e8c25a7d3af.png?x-oss-process=image/resize,w_1400/format,webp)
DispatchServlet
2.1 判断是否为MultiPart请求
![img_7a2ba4e21c4710389cc73c217c9b21c0.png](https://yqfile.alicdn.com/img_7a2ba4e21c4710389cc73c217c9b21c0.png?x-oss-process=image/resize,w_1400/format,webp)
StandardServletMultipartResolver
2.2 解析MultiPart请求。
![img_07888cc6b7a5b98e1ad4d8405bf6996a.png](https://yqfile.alicdn.com/img_07888cc6b7a5b98e1ad4d8405bf6996a.png?x-oss-process=image/resize,w_1400/format,webp)
StandardServletMultipartResolver
3、具体解析流程。Part为底层原生的API,可以通过HttpServletRequest直接调用。然后将请求的Part参数封装起来。
![img_0a82e97038c4cf732cfaed3644eb27bc.png](https://yqfile.alicdn.com/img_0a82e97038c4cf732cfaed3644eb27bc.png?x-oss-process=image/resize,w_1400/format,webp)
StandardMultipartHttpServletRequest
3.1 我们可以看到前端mutipart/form-data上传请求的类型为
![img_0ef83f1d979e1201a9f548b1c685c982.png](https://yqfile.alicdn.com/img_0ef83f1d979e1201a9f548b1c685c982.png?x-oss-process=image/resize,w_1400/format,webp)
表单请求部分
4、创建了MultiPartFile实现。前端表单上传的MultiPart部分都从Part获取。
![img_d7b3edfbd8a01654d546e557f4b449d1.png](https://yqfile.alicdn.com/img_d7b3edfbd8a01654d546e557f4b449d1.png?x-oss-process=image/resize,w_1400/format,webp)
StandardMultipartFile
5、在Controller中则可以使用参数映射来获取上传的MultiPart部分。
![img_5e23fe364ab0e94bad1f059808189363.png](https://yqfile.alicdn.com/img_5e23fe364ab0e94bad1f059808189363.png?x-oss-process=image/resize,w_1400/format,webp)
Controller文件
小结
这次主要解析了StandardServletMultipartResolver,关于Apache下的CommonsMultipartResolver处理过程也大体相当,可自行解析。通过这次分析在后台解析文件的请求处理上,可定制更加灵活的方案来处理。