springmvc/springboot 上传文件(Servlet3.0支持)
程序员文章站
2024-03-24 09:16:10
...
Controller代码
/**
* 文件上传
* @param
* @return
*/
@ResponseBody
@RequestMapping(value = "/uploadMiltiFile",consumes = "multipart/form-data", method = RequestMethod.POST)
public String instantUploadMiltiFile(HttpServletRequest request, String account) {
MultipartHttpServletRequest muti = (MultipartHttpServletRequest) request;
MultiValueMap<String, MultipartFile> map = muti.getMultiFileMap();
for (Map.Entry<String, List<MultipartFile>> entry : map.entrySet()) {
List<MultipartFile> list = entry.getValue();
for (MultipartFile multipartFile : list) {
try {
read(multipartFile.getInputStream());
} catch (Exception ex) {
}
}
}
return "上传文件";
}
MultipartFile的getInputStream()方法可以获取InputStream。接下去read函数就可以处理了
这里有个奇怪的地方就是 MultipartHttpServletRequest muti = (MultipartHttpServletRequest) request;为什么request可以转型成MultipartHttpServletRequest,我们看看请求在到达Controller做了什么。
实际上在请求到达DispatcherServlet通过进行了请求的转型。主要进行了两个步骤,一个是判断请求是上传文件类型,另外一个是对请求进行转型。关键函数是checkMultipart。
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
this.logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, this typically results from an additional MultipartFilter in web.xml");
} else if (this.hasMultipartException(request)) {
this.logger.debug("Multipart resolution failed for current request before - skipping re-resolution for undisturbed error rendering");
} else {
try {
return this.multipartResolver.resolveMultipart(request);
} catch (MultipartException var3) {
if (request.getAttribute("javax.servlet.error.exception") == null) {
throw var3;
}
}
this.logger.debug("Multipart resolution failed for error dispatch", var3);
}
}
return request;
}
实际上调用了multipartResolver的isMultipart方法。multipartResolver是接口,它默认标准实现是StandardServletMultipartResolver那我们看下StandardServletMultipartResolver.isMultipart方法
public boolean isMultipart(HttpServletRequest request) {
if (!"post".equalsIgnoreCase(request.getMethod())) {
return false;
} else {
String contentType = request.getContentType();
return StringUtils.startsWithIgnoreCase(contentType, "multipart/");
}
}
转换的逻辑是return this.multipartResolver.resolveMultipart(request);实际上也是调用StandardServletMultipartResolver.resolveMultipart方法。我们看下方法的源码
public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
return new StandardMultipartHttpServletRequest(request, this.resolveLazily);
}
调了StandardMultipartHttpServletRequest的构造
public StandardMultipartHttpServletRequest(HttpServletRequest request, boolean lazyParsing) throws MultipartException {
super(request);
if (!lazyParsing) {
this.parseRequest(request);
}
}
private void parseRequest(HttpServletRequest request) {
try {
Collection<Part> parts = request.getParts();
this.multipartParameterNames = new LinkedHashSet(parts.size());
MultiValueMap<String, MultipartFile> files = new LinkedMultiValueMap(parts.size());
Iterator var4 = parts.iterator();
while(var4.hasNext()) {
Part part = (Part)var4.next();
String headerValue = part.getHeader("Content-Disposition");
ContentDisposition disposition = ContentDisposition.parse(headerValue);
String filename = disposition.getFilename();
if (filename != null) {
if (filename.startsWith("=?") && filename.endsWith("?=")) {
filename = StandardMultipartHttpServletRequest.MimeDelegate.decode(filename);
}
files.add(part.getName(), new StandardMultipartHttpServletRequest.StandardMultipartFile(part, filename));
} else {
this.multipartParameterNames.add(part.getName());
}
}
this.setMultipartFiles(files);
} catch (Throwable var9) {
this.handleParseFailure(var9);
}
}
这里还有一个疑问就是 Collection<Part> parts = request.getParts();
实际上在Servlet3.0支持request.getParts()获取上传文件
推荐阅读
-
springmvc/springboot 上传文件(Servlet3.0支持)
-
SpringBoot+Vue.js实现前后端分离的文件上传
-
Vue+SpringBoot实现前后端分离的文件上传
-
python ftp上传下载文件,支持断点续传 博客分类: python
-
spring mvc 实现上传文件进度条 博客分类: SPRINGSPRING MVC springmvc
-
Servlet 3.0 新特性 实现文件上传 servlet3.0 文件上传 MultipartConfig
-
Servlet 3.0 新特性 实现文件上传 servlet3.0 文件上传 MultipartConfig
-
Springmvc3实现文件上传 博客分类: spring springmvcjsonservlet
-
springmvc采用formdata进行多文件上传 博客分类: spingMVCspringjava
-
SpringMVC上传文件踩过的坑