概念
web应用中,文件上传的功能的非常普遍。在spring mvc中,带有文件的request会是MultipartHttpServletRequest,上传的文件会抽象成MultipartFile对象,而上传的相关功能由MultipartResolver处理
使用
托spring boot的福,在spring boot的环境下,文件上传功能是开箱即用的,你啥都不用配置就可以直接用了
@PostMapping(value = "/file")
public int file(MultipartFile file) throws IOException {
return file.getBytes().length;
}
实现
主要角色
MultipartFile
先看MultipartFile,在spring mvc中,上传的一个文件就会转化成一个MultipartFile
public interface MultipartFile extends InputStreamSource {
String getName();
String getOriginalFilename();
String getContentType();
boolean isEmpty();
//文件大小,单位字节
long getSize();
//返回文件的字节数组表示
byte[] getBytes() throws IOException;
InputStream getInputStream() throws IOException;
//转换为Resource
default Resource getResource() {
return new MultipartFileResource(this);
}
void transferTo(File dest) throws IOException, IllegalStateException;
default void transferTo(Path dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest));
}
}
Multipart的具体实现
- CommonsMultipartFile:当使用Apache Commons FileUpload时的实现
- MockMultipartFile:测试用
- StandardMultipartHttpServletRequest.StandardMultipartFile:默认实现
MultipartRequest
再看上传文件的请求,在spring mvc中,如果请求包含文件,它的类型就会是MultipartRequest
public interface MultipartRequest {
//获取所有的文件名
Iterator<String> getFileNames();
//根据文件名获取文件
MultipartFile getFile(String name);
//根据文件名获取文件
List<MultipartFile> getFiles(String name);
Map<String, MultipartFile> getFileMap();
//注意,这个MultiValueMap的value是个List
MultiValueMap<String, MultipartFile> getMultiFileMap();
String getMultipartContentType(String paramOrFileName);
}
MultipartRequest的实现
- MultipartHttpServletRequest:接口,组合了MultipartRequest和HttpServlertRequest
- AbstractMultipartHttpServletRequest:抽象实现类
- DefaultMultipartHttpServletRequest:使用apache common file upload时的实现
- StandardMultipartHttpServletRequest:默认实现
MultipartResolver
最后一个重要角色是MultipartResolver:
public interface MultipartResolver {
//判断请求是否需要上传文件,一般就是根据Content-Type是不是multipart/form-data判断
boolean isMultipart(HttpServletRequest request);
//将普通的request转换成MultipartHttpServletRequest
MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException;
//清理处理文件上传期间使用的资源
void cleanupMultipart(MultipartHttpServletRequest request);
}
MultipartResolver的实现
- CommonsMultipartResolver:使用apache common file upload时的实现
- StandardServletMultipartResolver:默认实现
处理过程
- 接受到请求后,判断请求header的Content-Type字段值是不是multipart开头
- 如果是multipart开头,则使用MultipartResolver将request处理成MultipartFileRequest:将文件处理成Part对象,放入MultipartFileRequest对象内
- 处理结束后调用cleanupMultipart,清理资源
结语
这个部分主要涉及了三个重要角色:
- MultipartFile
- MultipartRequest
- MultipartResolver
共计12个类。
(水平有限,最近在看spring源码,分享学习过程,希望对各位有点微小的帮助。
如有错误,请指正~)