springboot2.6+上传文件失败?

项目中自定义了一个过滤器继承 OncePerRequestFilter

public class OnceFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ServletRequest requestWrapper = null;
        setRequestChainInfo(request);
        if(request instanceof HttpServletRequest) {
            requestWrapper = new RequestWrapper( request);
        }
        // 让下一个filter生效
        if(requestWrapper == null) {
            filterChain.doFilter(request, response);
        } else {
            filterChain.doFilter(requestWrapper, response);
        }
        // 清除MDC
        MDC.clear();
    }


    /**
     * 设置整个请求链路信息
     * @param req HttpServletRequest
     */
    private void setRequestChainInfo(HttpServletRequest req) {
        String traceId = req.getHeader(CoreCommonConstant.TRACE_ID);
        if (StringUtils.isBlank(traceId)) {
            traceId = CsRandomUtil.randomUUID(true,true);
        }
        req.setAttribute(CoreCommonConstant.TRACE_ID,traceId);
        MDC.put(CoreCommonConstant.TRACE_ID, traceId);
        // 设置用户信息
        MDC.put(CoreCommonConstant.USER_INFO,req.getHeader(CoreCommonConstant.USER_INFO));
    }


}

但是上传文件的时候报错,

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

然后我把这个过滤其注释后就可以上传了,
我想保留这个过滤器,还有其它办法可以解决上传的问题吗??

yml配置项:

spring:
   mvc:
      hiddenmethod:
         filter:
            enabled: true
   servlet:
      multipart:
         enabled: true
         location: /upload_tmp
         max-file-size: 10MB   #设置单个上传的文件大小
         max-request-size: 20MB  #设置单次请求的文件的总大小
阅读 3.3k
3 个回答

过滤器你不会是读一次文件,然后接口你又读一次文件吧?

Multipart流只能读一次吧. 要么包装请求, 把这个流缓存一下, 要么把流用完reset一下.

你这个拦截器的目的是对HttpServletRequest请求进行相关自定义操作,具体的需要看RequestWrapper这个类的内容
这里前端上传会发送一个MultipartServletRequest,他是HttpServletRequest的一个特殊的实现,所以会走

if(request instanceof HttpServletRequest) {
            requestWrapper = new RequestWrapper( request);
        }

在这里发生了类型转换,返回的requestWrapper是一个ServletRequest,这是一个擦除,对正常的parameter,body这种请求影响不大,但是对multipart后续处理会有影响。

这里一般需要再次判断request instanceof MultipartServletRequest,可以直接下传,或者根据需要单独实现一个针对multipart的request servlet wrapper,保证返回类型后继续下传

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏