org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed

文件上传报org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed

先上解决方式:

在yml或者其他配置文件中添加如下配置即可

Spring:
mvc:
  hiddenmethod:
    filter:
      enabled: true

问题解决完毕、梳理下问题点【可忽略如下内容】

最近突然发现项目的上传功能失效了,一顿操作发现错误是:

org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed

尝试着各种解决未果,百度又是各种牛头不对马嘴。折腾了几个小时,皇天不负有心人。终于找到了一位老哥在gitmemory上提交的问题

url:https://www.gitmemory.com/issue/spring-projects/spring-boot/18644/583836701

问题:

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

思路:

I ran into the same issue.

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

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 HttpServletRequest with a caching wrapper and closed the input stream before passing the request along the filter chain. This caused an issue when javax.servlet.http.HttpServletRequest#getParts was 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 hiddenHttpMethodFilter no longer being present in the filter chain. Previously this filter would be one of the first filters to be called, and it would call HttpServletRequest#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 #getParts would use that and not try to parse them again).

I reported this to Logback: https://jira.qos.ch/browse/LOGBACK-1503

Workaround - call HttpServletRequest#getParameter before 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.

logback链接:

https://jira.qos.ch/browse/LOGBACK-1503

解析:

上面的老哥分析我看的也是一致半解

他是项目在升级到springboot2.2+时候出现的问题与我的问题一致,简单的查看可知在springboot2.2+中把 META-INF/spring-configuration-metadata.json 配置文件中把spring.mvc.hiddenmethod.filter.enabled设置为了false

{
      "name": "spring.mvc.hiddenmethod.filter.enabled",
      "type": "java.lang.Boolean",
      "description": "Whether to enable Spring's HiddenHttpMethodFilter.",
      "defaultValue": false
    }

至于为什么会出现这个问题,emmm我还得梳理下源码【待补充】

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值