【问题标题】:MultipartFile is null when I use CommonsMultipartResolver in my Spring Boot app当我在 Spring Boot 应用程序中使用 CommonsMultipartResolver 时,MultipartFile 为空
【发布时间】:2016-10-23 10:10:10
【问题描述】:

我想在我的 Spring Boot 应用程序中实现上传处理程序方法。我想使用CommonsMultipartResolver 而不是StandardServletMultipartResolver。我有以下问题:

我的控制器方法参数(文件)始终设置为空。我在HiddenHttpMethodFilter 的java 文档中看到: 在多部分 POST 请求的情况下,此过滤器需要在多部分处理之后运行,因为它固有地需要检查 POST 正文参数。

我尝试为 multipartFilter bean 设置顺序,但没有帮助。当我调试时,我看到HiddenHttpMethodFilter 总是在MultipartFilter 之前被调用。我正在使用 Spring Boot 版本 1.3.0.RELEASE 和基于 Java 的配置。如何设置HiddenHttpMethodFilterMultipartFilter 之后的顺序?

@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver resolver = new CommonsMultipartResolver();        
    resolver.setMaxUploadSizePerFile(52428800); 
    return resolver;
}

@Bean
@Order(0)
public MultipartFilter multipartFilter() {
        MultipartFilter multipartFilter = new MultipartFilter();
    multipartFilter.setMultipartResolverBeanName("multipartResolver");
    return multipartFilter;
}

@RequestMapping(value = "/{userId}", method = RequestMethod.POST)
@ResponseBody
public FileTransport create(@PathVariable("userId") Long userId,
        MultipartFile file) throws IOException {
    //return fileService.create(userId, file);
    return new FileTransport();
}

如果我修改方法以包含如下请求参数:

@RequestParam(name = "file", required = true) MultipartFile 文件

它抛出一个异常:'Required MultipartFile parameter 'file' is not present'。

如果我使用StandardServletMultipartResolver,一切都会按预期进行。

【问题讨论】:

  • 因为discussed on GitHub 已经是你的MultipartFilter 的顺序是错误的。它需要小于 HiddenHttpMethodFilter 的数量级,即 -10000。如果这没有帮助,你能提供一个minimal, complete, verifiable example吗?
  • @AndyWilkinson HiddenHttpMethodFilter 的顺序不是-10000,而是HIGHEST_PRECEDENCE+10。但即使你在它前面设置了 MultipartFilter,上传也会失败,这次是 java.io.IOException: Missing content for multipart request at org.eclipse.jetty.server.Request.extractMultipartParameters(Request.java:390)。 CommonsMultipartResolver 是否与 Spring Boot 完全兼容?
  • @AndyWilkinson spring-boot 版本是 1.2.8。
  • @kpentchev 您使用的是不同版本的 Spring Boot,因此情况可能不一样。评论不是解决问题的正确地方;如果这个问题没有帮助,请提出一个新问题。

标签: spring file-upload spring-boot


【解决方案1】:

在 Spring Boot 中要使用 CommonsMultipartResolver,您需要通过在配置中添加以下注释来禁用 MultipartAutoConfiguration:

@EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class})

我的多部分解析器 bean:

 @Bean
 public MultipartResolver multipartResolver() {
     CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
     multipartResolver.setMaxUploadSize(5 * 1024 * 1024);
     return multipartResolver;
 }

【讨论】:

    【解决方案2】:

    如果有人遇到 PUT 请求的问题,您需要扩展 CommonsMultipartResolver 并覆盖 isMultipart 方法。然后将这个新类用作 MultipartResolver bean。

    public class CustomCommonsMultipartResolver extends CommonsMultipartResolver {
        @Override
        public boolean isMultipart(HttpServletRequest request) {
            String contentType = new ServletRequestContext(request).getContentType();
            if (contentType == null) {
                return false;
            }
            if (contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/")) {
                return true;
            }
            return false;
        }
    }
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,下面的代码对我有用:

      @Bean(name = "multipartResolver")
      public CommonsMultipartResolver createMultipartResolver() {
      
        final CommonsMultipartResolver cmr = new CommonsMultipartResolver();
        long maxSize = parseSize(multipartConfig.getMaxFileSize());
        cmr.setMaxUploadSize(maxSize);
        cmr.setDefaultEncoding("UTF-8");
        cmr.getFileUpload().setProgressListener(
            (long pBytesRead, long pContentLength, int pItems) -> {
              LOG.info(" Uploaded {}% ", pBytesRead*100/pContentLength);
            });
      
        return cmr;
      }
      
      @Bean
      @Order(0)
      public MultipartFilter multipartFilter() {
          MultipartFilter multipartFilter = new MultipartFilter();
          multipartFilter.setMultipartResolverBeanName("multipartResolver");
          return multipartFilter;
      }
      

      【讨论】:

        【解决方案4】:

        根据this article,在使用 CommonsMultipartResolver 时正确处理一个人的多部分请求非常重要,而后者又依赖于 commons-fileupload。 我将遵循this post 中的建议。请注意我们如何设置多部分请求内容类型和内容处置。

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        
            MultiValueMap<String, String> fileHeaders = new LinkedMultiValueMap<>();
            fileHeaders.add("Content-type", MediaType.TEXT_PLAIN_VALUE);
            fileHeaders.add("Content-disposition", "form-data; name=file; filename=originalFileName.txt");
            File myFile = new File(...);
            HttpEntity multipartFile = new HttpEntity<>(myFile.getBytes(), fileHeaders);
        
            MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
            form.add("file", multipartFile);
        
            ResponseEntity<String> response = new RestTemplate().postForEntity("http://localhost:8080/file/", new HttpEntity<>(form, headers), String.class);
            System.err.println(response.toString());
        

        希望对你有帮助。

        【讨论】:

          【解决方案5】:

          我认为他们已经解决了 Spring-Boot 1.4.2.RELEASE 版本中的问题:

          @Bean
          public CommonsMultipartResolver multipartResolver() {
              CommonsMultipartResolver multipart = new CommonsMultipartResolver();
              multipart.setMaxUploadSize(3 * 1024 * 1024);
              return multipart;
          }
          
          @Bean
          @Order(0)
          public MultipartFilter multipartFilter() {
              MultipartFilter multipartFilter = new MultipartFilter();
              multipartFilter.setMultipartResolverBeanName("multipartResolver");
              return multipartFilter;
          }
          

          还需要排除Spring-Boot的MultipartAutoConfiguration.class

          @EnableAutoConfiguration(exclude = {MultipartAutoConfiguration.class})
          

          这对我有用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-08-26
            • 2022-01-10
            • 2016-12-24
            • 1970-01-01
            • 1970-01-01
            • 2022-06-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多