目录
- multipart原理简介
- multipart的流是服务器临时文件流
- multipartfile生成临时文件到默认文件夹
- 临时文件的目录可配
- Mutipartfile的文件默认来自临时文件
- Mutipartfile产生临时文件的好处坏处
-
- 纯流式上传application/octet-stream
multipart原理简介
multipart的流是服务器临时文件流
multipart的流不是HTTPRequest的流,而是服务器的临时文件流
multipart/form-data是表单上传,接口可以从Mutipartfile对象获取输入流getInputStream,表面上看没产生临时文件
org.springframework.web.multipart.support.StandardMultipartHttpServletRequest的getInputStream
@Override
public InputStream getInputStream() throws IOException {
return this.part.getInputStream();
}
这里面的流是从DiskFileItem(一眼磁盘)拿的,还告诉了你临时目录位置location
multipartfile生成临时文件到默认文件夹
从原理上看,在tomcat源码的org.apache.catalina.connector.Request类中,parseParts方法就将multipart格式的请求中文件生成到临时文件夹
File location;
String locationStr = mce.getLocation();
if (locationStr == null || locationStr.length() == 0) {
location = ((File) context.getServletContext().getAttribute(
ServletContext.TEMPDIR));
} else {
location = new File(locationStr);
if (!location.isAbsolute()) {
location = new File(
(File) context.getServletContext().getAttribute(ServletContext.TEMPDIR),
locationStr).getAbsoluteFile();
}
}
临时文件的目录可配
这个location就是javax.servlet.MultipartConfigElement的配置,可以通过spring.servlet.multipart系列配置的location指定临时文件目录,这个临时文件用完,也会被自动清除
private final String location;
private final long maxFileSize;
private final long maxRequestSize;
private final int fileSizeThreshold;
Mutipartfile的文件默认来自临时文件
Mutipartfile的注释中说明了,文件是stored in memory or temporarily on disk,存在内存或磁盘临时文件的,所以上传大文件时,会发现前端进度条走完了,代码才走进自己写得接口代码
public interface MultipartFile extends InputStreamSource {
Mutipartfile产生临时文件的好处坏处
好处
帮开发封装了上传逻辑
可以在此基础实现切片上传到本地最后合并
坏处
对我来说
文件转储时间翻倍:我的文件存储服务器不是接收请求的服务所在服务器,我还得把文件转存到文件服务器,而服务到文件服务器还得再传一遍,时间基本double
前端进度不真实:前端显示的上传进度仅是浏览器给到服务的进度
占用资源:临时文件多少占点服务器磁盘空间
纯流式上传application/octet-stream
一段半伪代码,application/octet-stream参数体只能有文件,参数通过放headers里给就可以解决这个问题
@PostMapping(value = "/upload", headers = "content-type=application/octet-stream;charset=utf-8")
public Object upload(HttpServletRequest request,
@RequestHeader("userId") String userId,
@RequestHeader("fileName") String fileName,
@RequestHeader("fileSize") String fileSize,
@RequestHeader("dirId") String dirId) {
try (InputStream in = request.getInputStream()) {
fileName = URLDecoder.decode(fileName,"utf-8");
uploadFileServer(in, fileName, fileSize, userId, dirId);
return "success";
} catch (Exception e) {
log.error("上传报错", e);
return "error";
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)