Spring 引导升级到 2.2.5 导致所需的请求部分 'file' 不存在

Spring Boot upgrade to 2.2.5 causing required request part 'file' is not present

因此我们将 Spring 引导从 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... 的响应。看起来文件没有正确填充。

所以发生的事情是:

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

这在 Spring InputStream 魔术和普通 servlet 过滤器模式之间有点冲突。 Spring 对待内部结构的方式与外部人员调用其代码的方式不同。因为从技术上讲,request.getParts() 不应被允许根据 Spring 自己的规则来操纵流。