1、文件上传
(1)创建html文件表单 user_info.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form th:action="@{/upload}" method="post" enctype="multipart/form-data">
<input type="text" name="username" class="form-control" placeholder="用户名" autofocus>
<input type="password" name="password" class="form-control" placeholder="密码">
<input type="file" name="header_url" placeholder="头像">
<input type="file" name="photos" placeholder="生活照片" multiple>
<button type="submit" >提交</button>
</form>
</body>
</html>
(2)配置路由器
@Slf4j
@Controller
public class UserController {
@GetMapping("/user/save")
public String saveUserInfoPage(){
return "file/user_info";
}
@PostMapping("/upload")
public String saveUserInfo(@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestPart("header_url") MultipartFile headerUrl,
@RequestPart("photos") MultipartFile[] photos) throws IOException {
log.info("用户名:{},密码:{},头像文件名称:{},生活照几张:{}",username,password,headerUrl.getName(),photos.length);
if (!headerUrl.isEmpty()){
headerUrl.transferTo(new File("/Users/djy/Desktop/tmp/"+headerUrl.getOriginalFilename()));
}
for (MultipartFile file : photos){
if (!file.isEmpty()){
file.transferTo(new File("/Users/djy/Desktop/tmp/"+file.getOriginalFilename()));
}
}
return "redirect:/index.html";
}
}
(3)默认文件单个最大才1兆,单次请求文件总大小10兆,不够用,所以修改文件上传大小
#修改单个最大文件上传尺寸
spring.servlet.multipart.max-file-size=10MB
#修改单个请求所有文件总和大小
spring.servlet.multipart.max-request-size=100MB
2、文件上传原理
1、自动配置都存在MultipartAutoConfiguration中
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class })
@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(MultipartProperties.class)
public class MultipartAutoConfiguration {
配置了文件上传解析器StandardServletMultipartResolver
@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) @ConditionalOnMissingBean(MultipartResolver.class) public StandardServletMultipartResolver multipartResolver() { StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver(); multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily()); return multipartResolver; }
步骤
1、请求进来使用文件上传解析器(isMultipart)判断并调用resolveMultipart封装成MutipartHttpServletRequest请求文件上传请求
@Override public boolean isMultipart(HttpServletRequest request) { return StringUtils.startsWithIgnoreCase(request.getContentType(), (this.strictServletCompliance ? MediaType.MULTIPART_FORM_DATA_VALUE : "multipart/")); }
@Override public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException { return new StandardMultipartHttpServletRequest(request, this.resolveLazily); }
2、通过RequestPartMethodArgumentResolver来解析
- 深处解析代码就是通过从提前封装好的MultipartHttpServletRequest中获取MultipartFile文件。
List<MultipartFile> files = multipartRequest.getFiles(name);