【发布时间】:2021-12-21 14:05:49
【问题描述】:
我使用类似于以下 curl 变体的上传请求的分段文件上传:
curl --request POST 'http://localhost:8080/api/upload' --form 'csv=@"/path/file.csv"'
在浏览器中查看表单数据如下:
------WebKitFormBoundarysT6cYRLsXHQ8EWtZ
Content-Disposition: form-data; name="csv"; filename="file.csv"
Content-Type: text/csv
------WebKitFormBoundarysT6cYRLsXHQ8EWtZ--
我的 Java 代码如下所示:
@PostMapping(value = "/api/upload")
public ResponseEntity<String> upload(@RequestBody MultipartFile csv) {
System.out.println(new String(csv.getBytes(), StandardCharsets.UTF_8));
return ResponseEntity.ok().body(null);
}
它曾经在 Spring Boot 2.0 上运行良好,但一旦我升级到 Spring Boot 2.4/2.5,csv 参数始终为空,因此csv.getBytes() 抛出 NullPointerException。
到目前为止我已经尝试过:
- 将
@RequestBody更改为@RequestPart("csv")或@RequestParam("csv")会使上传请求返回 HTTP 400 代码,并显示消息“必需的请求部分 'csv' 不存在” - 将
consumes = MediaType.MULTIPART_FORM_DATA_VALUE添加到@PostMapping没有任何区别。
我发现默认情况下 Spring Boot 使用 StandardServletMultipartResolver,因为 MultipartAutoConfiguration 已启用,可以在这里看到 - https://github.com/spring-projects/spring-boot/blob/v2.4.13/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/MultipartAutoConfiguration.java
我找到了一种解决方法 - 添加 CommonsMultipartResolver 作为默认解析器而不是 StandardServletMultipartResolver 可以解决问题。这可以通过添加新的依赖项和相应的 bean 来完成:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
但是 Spring 不鼓励使用 CommonsMultipartResolver,如 https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.spring-mvc.multipart-file-uploads 所示
建议使用容器的内置支持 分段上传,而不是引入额外的依赖 例如 Apache Commons 文件上传。
这就是我想使用内置支持的原因。任何想法如何解决它?
【问题讨论】:
-
尝试https://www.baeldung.com/spring-file-upload,第 7 节。Spring Boot 文件上传
-
你有 spring-boot-starter-web 依赖吗?我正在使用 @RequestParam(value = "csv") MultipartFile 文件,它工作正常
-
@MarcStroebel 谢谢,但是 spring-boot-starter-web 和 spring.servlet.multipart.enabled 都已经就位了。
-
@DeepanshuRathi 确实我的项目中已经有了这个依赖项。
-
@lagivan 我遇到了同样的问题:在 Spring 从 2.3.5.RELEASE 升级到 2.6.2 之后,“必需的请求部分 'myFileName' 不存在”。有关使其与 StandardServletMultipartResolver 一起使用的任何消息?
标签: java spring spring-boot