无法将 Apache Commons FileUpload 与 Spring Boot multipart.resolve-lazily 一起使用

Posted

技术标签:

【中文标题】无法将 Apache Commons FileUpload 与 Spring Boot multipart.resolve-lazily 一起使用【英文标题】:Cannot use Apache Commons FileUpload with Spring Boot multipart.resolve-lazily 【发布时间】:2019-07-15 17:49:12 【问题描述】:

我正在使用 Spring Boot 框架构建一个 REST API。有一个端点,用户可以上传一个大文件(~1GB)。我正在使用来自 Apache Commons FileUpload 的 Streaming API。

我只想在该端点启用流式传输。因此,我将我的 Spring Boot 配置如下:

spring.servlet.multipart.enabled = true
spring.servlet.multipart.resolve-lazily = true
spring.servlet.multipart.max-file-size = 2GB
spring.servlet.multipart.max-request-size = 2GB

这是我的终点:

@PostMapping(path = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> importData(HttpServletRequest request) throws IOException, FileUploadException 
    System.out.println("Streaming...");

    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    if (!isMultipart) 
        return ResponseEntity.badRequest().build();
    

    ServletFileUpload upload = new ServletFileUpload();
    FileItemIterator iterStream = upload.getItemIterator(request);
    while (iterStream.hasNext()) 
        System.out.println("Iterating...");

        FileItemStream item = iterStream.next();

        if (!item.isFormField()) 

            String name = item.getFieldName();
            System.out.println("Field name is: " + name);

            try (InputStream uploadedStream = item.openStream();
                 OutputStream out = new FileOutputStream("file.zip")) 

                IOUtils.copy(uploadedStream, out);
            

         else 

            try (InputStream stream = item.openStream()) 
                String formFieldName = item.getFieldName();
                String formFieldValue = Streams.asString(stream);
                System.out.println(String.format("Form field found - %s: %s", formFieldName, formFieldValue));
            
        
    

    return ResponseEntity.ok("Data streamed successfully.");

调用方法并执行代码。但是,FileItemIterator 是空的,那里的while 循环没有被执行。

如果我设置spring.servlet.multipart.enabled = false,此代码将完美运行。但我不想这样做,因为正如我所说,我不想全局禁用 Spring Boot Multipart Resolver,但只能在这个端点上。

那么,我的代码有什么问题?为什么FileItemIterator 是空的?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

我解决了我的问题。

我认为问题出在 Spring StandardServletMultipartResolver。当我切换到CommonsMultipartResolver(如下配置)时,我的代码运行良好。

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() 
    CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    resolver.setDefaultEncoding("UTF-8");
    resolver.setResolveLazily(true);
    return resolver;

【讨论】:

您好,感谢您的回答。不幸的是,它并没有为我解决问题。 iterStream.hasNext() 从一开始就返回 false。我正在使用一些拦截器和 Spring Security,它们可能会在请求到达我的控制器之前弄乱请求。就您而言,您是否还有 Spring Security 和例如正在使用 LocaleChangeInterceptor?提前致谢。 嗨,我有 Spring Security 但没有拦截器。 好的,我可以确认通过禁用拦截器,hasNext() 已经开始返回 true。感谢您的反馈。 要禁用特定 URL 的拦截器,请执行以下操作: @Override public void addInterceptors(final InterceptorRegistry registry) registry.addInterceptor(localeChangeInterceptor()).addPathPatterns("/**").excludePathPatterns ("/the/endpoint/you/use/for/upload");

以上是关于无法将 Apache Commons FileUpload 与 Spring Boot multipart.resolve-lazily 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

org.apache.commons 无法解析为类型

eclipse juno 中无法解析导入 org.apache.commons

pyspark.sql 无法实例化 HiveMetaStoreClient - noclassfound from org.apache.commons.dbcp.connectionfactory

Apache Commons VFS - 无法解析文件

未指定标头映射,无法按名称访问记录值(Apache Commons CSV)

使用 Apache Commons Compress 库以非机器依赖的方式将文件和目录添加到 Tar 存档