【问题标题】:Spring Boot upgrade to 2.2.5 causing required request part 'file' is not presentSpring Boot 升级到 2.2.5 导致所需的请求部分“文件”不存在
【发布时间】:2020-05-12 13:39:06
【问题描述】:

所以我们将 Spring Boot 从 2.0.3 升级到 2.2.5,这导致我们的文件导入开始失败。 所以我的代码是这样的:

public Result<FileResponse> importFile(@RequestParam(value = "file") MultipartFile file) {...}

我们有几个自定义过滤器,我们在嵌入式 Tomcat 9.0.3 上运行。我们收到类似于...required request part 'file' is not present... 的响应,带有堆栈跟踪。看起来文件没有正确填充。

【问题讨论】:

    标签: spring-boot servlet-filters


    【解决方案1】:

    所以发生的事情是:

    1. Spring Boot 2.0.3 具有某些过滤器
    2. HiddenHttpProcessor 过滤器运行代码request.getParts()。
    3. 因此运行它实际上会导致 Spring 执行魔术,其中 Spring 从输入流中读取,解析请求部分,填充请求部分,从流中删除请求部分,然后 Spring 就像从未读取过流一样。
    4. Spring Boot 升级到 2.2.5 导致过滤器运行的变化。因此,request.getParts() 在我们的自定义过滤器运行之前从未运行过。
    5. 我们的自定义过滤器之一是包装请求。在创建打包请求期间,我们运行了IOUtils.copy(this.request.getInputStream(),baos),它将我们的request.getInputStream() 复制到ByteArrayOutputStream。 这是为了绕过 Spring 的规则,即只允许调用一次 request.getInputStream()。
    6. 出于某种原因,将request.getInputStream() 转换为任何类型的字节数组会将流更改为request.getParts() 无法正确解析它的程度。
    7. 因此您必须在操作request.getInputStream() 之前调用request.getParts()。

    这有点像 Spring InputStream 魔法和普通 servlet 过滤器模式之间的冲突。 Spring 对待他们内部的方式与外界如何称呼他们的代码不同。因为从技术上讲,request.getParts() 不应该被允许通过 Spring 自己的规则来操作流。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-06
      • 2019-09-08
      • 2017-10-09
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多