当前位置: 首页 > 知识库问答 >
问题:

Spring Boot File Upload-升级到Spring Boot 2.4后部分为空

漆雕原
2023-03-14

我对上传请求使用多部分文件上传,类似于下面的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引导2.0上工作正常,但是一旦我升级到Spring引导2.4 / 2.5,csv参数总是为空,所以csv.getBytes()会抛出空点代表。

到目前为止,我所做的努力:

    < li >将< code>@RequestBody更改为< code>@RequestPart("csv")或< code > @ request param(" csv ")会使上载请求返回HTTP 400代码,并显示消息“所需的请求部分' CSV '不存在” < li >添加< code>consumes = MediaType。MULTIPART _ FORM _ DATA _ VALUE 到< code>@PostMapping没有区别。

我发现默认情况下Spring Boot使用StandardServletMultipartResolver,因为启用了MultipartAutoConfigurationhttps://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/how to . html # how to . Spring-MVC . multipart-file-uploads上看到

建议使用容器对多部分上传的内置支持,而不是引入额外的依赖项,例如Apache Commons File Upload。

这就是为什么我想使用内置支持。有什么想法如何解决吗?


共有1个答案

怀浩大
2023-03-14

在身份验证过滤器之前添加过滤器为我修复了问题。与标准服务器多个部分解决方案一起使用

public class HttpRequestPartsInitFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
    if(StringUtils.startsWithIgnoreCase(request.getContentType(), "multipart/")) {
        if (request.getParts().isEmpty()) {
            log.info("Request.getParts() is empty for={}", request.getPathInfo());
        } else {
            log.info("Request.getParts() is NOT empty for={}", request.getPathInfo());
        }
    }
    filterChain.doFilter(request, response);
}

}

我已经在扩展Web安全配置器适配器@Configuration类中注册了过滤器

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .addFilterBefore(new OktaErrorFilter(LOGIN_URL, OKTA_ERROR_URL),
                        OAuth2AuthorizationRequestRedirectFilter.class)
                .addFilterBefore(new HttpRequestPartsInitFilter(), OktaErrorFilter.class)
                ....        }

我找不到解释为什么它会起作用。这里提到的类似修复:Spring POST multipart/form-data,请求部分总是空的

 类似资料:
  • 我们最近将VS 2010和.NET 4应用程序升级为VS 2012和.NET 4.5。我们有一个构建脚本来在测试服务器上部署应用程序。我们有两个框-一个是Windows 8和VS 2012(新安装),另一个是Windows 7和VS 2010和VS 2012(新安装)。 从Windows 8运行构建脚本时,box构建脚本运行良好,并将应用程序部署到测试服务器。但从Windows 7 box部署应用

  • 我正在做一个简单的部分更新场景,它适用于Solr的6.x和7.x版本。将Solr和Solrj升级到8.8后,我遇到以下异常: 注意,这与前面关于stackoverflow的问题不同,因为我传递的是简单的整数字段,而在Solr/Lucene端,它被替换。

  • 我用Play2.0创建了一个应用程序。我实现了scribe-java库来使用一些OAuth服务。直到今天,一切都很好,但当我升级jdk并重新启动服务器时,我不能使用scribe-java库。它似乎在sun.security包中使用了和类,但找不到。 “java-version”返回: 播放2.0 StackTrace:

  • 最近对OSX Mavericks的升级中断了我的Rails应用程序的数据库连接。 当我尝试从数据库中提取时,服务器返回以下错误: 当尝试运行时,我得到: 我已经尝试了许多在互联网上可用的解决方案。例如重新安装pg gem并在my database.yml中设置host:localhost。我的/usr/local/var/postgres/pg_hba.conf文件显示: 返回哪个psql: 这件

  • 我正在运行《docker compose》中的jenkins,来自图片jenkins/jenkins。升级到Jenkins 2.277.1后,LDAP身份验证停止工作,我无法登录。我收到以下错误: 詹金斯。docker。new\u 1 | 2021 06-04 14:49:31.3110000[id=138]警告o.j.p.p.DiskUsageCollector#collect:无法获取磁盘使用