spring-boot: Upload file org.springframework.web.multipart.MultipartException
When updating Spring Boot to version 2.2.0 I get an error when trying to upload a file.
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed
Error code
@RestController
public class FileController {
@PostMapping("/api/file")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile multipartFile) {
//...
}
}
This code worked for me on versions less than 2.2.0
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 20 (5 by maintainers)
Open this filter and the problem will be solved
Change request method from PUT to post, the problem will be solved.
I ran into the same issue.
Worked fine on Spring Boot 2.1.12, failed after upgrade to 2.2.4 (both versions run the same embedded Tomcat 9.0.30).
The root cause was that we were using logback-access filter that logs requests and responses. The filter wrapped
HttpServletRequestwith a caching wrapper and closed the input stream before passing the request along the filter chain. This caused an issue whenjavax.servlet.http.HttpServletRequest#getPartswas called, as that call is delegated to the original Tomcat’s request (with a now-closed input stream), which then results in the “stream closed” exception.The Spring change that triggered this issue is
hiddenHttpMethodFilterno longer being present in the filter chain. Previously this filter would be one of the first filters to be called, and it would callHttpServletRequest#getParameter, which in turn would make Tomcat’s request implementation parse multipart content and store the parts in the object (so that later calls to#getPartswould use that and not try to parse them again).I reported this to Logback: https://jira.qos.ch/browse/LOGBACK-1503
Workaround - call
HttpServletRequest#getParameterbefore passing the request to logback’s filter (see LOGBACK-1503 for code), to force Tomcat to parse and store request parts while input stream is still open.@umanking 2.3 is likely to have the same issue but I don’t think there’s anything that we can do about this in Spring Boot. Someone needs to probably get involved with a fix for LOGBACK-1503.
@knight0707 if you share a small sample (a zip or a link to a github repo) that shows it work with 2.1x and fail with 2.2x (by just changing the version) we can reopen this issue.