实现文件上传功能
@Slf4j
@Controller
public class FormTestController {
@GetMapping("/form_layouts")
public String form_layouts() {
return "form/form_layouts";
}
@PostMapping("/upload")
public String upload(@RequestParam("email") String email,
@RequestParam("username") String username,
@RequestPart("headerImage") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos) throws Exception {
log.info("上传的信息:email={}, username={}, headerImg={}, photos={}",
email,username,headerImg.getSize(),photos.length);
//保存上传的文件
if (!headerImg.isEmpty()) {
String originalFilename = headerImg.getOriginalFilename();
headerImg.transferTo(new File("D:\\Java\\workspace_idea\\springboot-web-admin\\src\\main\\resources\\static\\images\\" + originalFilename));
}
if (photos.length > 0) {
for (MultipartFile photo : photos) {
if (!photo.isEmpty()) {
String originalFilename = photo.getOriginalFilename();
photo.transferTo(new File("D:\\Java\\workspace_idea\\springboot-web-admin\\src\\main\\resources\\static\\images\\" + originalFilename));
}
}
}
return "index";
}
}
文件上传原理
文件上传自动配置类MultipartAutoConfiguration
自动配置了文件上传解析器StandardServletMultipartResolver
处理文件上传请求时,会先调用checkMultipart
方法检查是否是上传文件的请求,如果是就会包装当前的请求为processedRequest
checkMultipart
方法是调用multipartResolver
文件上传解析器的isMultipart
方法来判断当前请求是否是文件上传请求,调用resolveMultipart
方法解析并返回解析后的请求
isMultipart
方法是根据请求的请求内容类型字段值,来判断是否是文件上传请求
resolveMultipart
方法会封装请求返回一个MultipartHttpServletRequest
类型的请求
然后执行目标方法
遍历所有的参数解析器,找到文件上传请求的参数解析器,解析请求中的文件内容,封装成MultiPartFile
执行文件上传请求,要先调用getMethodArgumentValues
方法获取目标方法的每一个参数的值
getMethodArgumentValues
方法会遍历所有的参数,利用文件上传的参数解析器调用resolveArgument
方法解析每一个参数的值并保存在数组中返回
resolveArgument
方法会先调用getArgumentResolver
方法来获取到文件上传请求的参数解析器,然后调用获取到的参数解析器调用它的resolveArgument
方法来解析参数
getArgumentResolver
会遍历所有的参数解析器,来查找到支持处理不同参数的参数解析器
文件上传请求参数解析的步骤:
- 请求进来,使用文件上传解析器调用
isMultipart
方法判断,并调用resolveMultipart方法封装请求,返回MultipartHttpServletRequest
类型的文件上传请求 - 参数解析器来解析请求中的文件内容,封装成
MultiPartFile
- 将
request
中文件信息封装成一个Map
集合MultiValueMap<String, MultipartFile>
,不同的文件参数名保存着不同的MultipartFile
,这样就解析完文件上传请求的参数