当我在Spring Boot应用程序中使用CommonsMultipartResolver时,MultipartFile为null

时间:2016-06-21 18:07:39

标签: spring file-upload spring-boot

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

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

我尝试为multipartFilter bean设置顺序,但它没有帮助。当我调试时,我发现在HiddenHttpMethodFilter之前总是调用MultipartFilter。我使用的是Spring Boot 1.3.0.RELEASE和基于Java的配置。如何设置HiddenHttpMethodFilter之后MultipartFilter的订单?

@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文件

它抛出一个异常:'所需的MultipartFile参数'文件'不存在'。

如果我使用StandardServletMultipartResolver,一切都按预期工作。

5 个答案:

答案 0 :(得分:7)

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

@EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class}

我的多部分解析器bean:

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

答案 1 :(得分:3)

我认为他们已经解决了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})

这对我有用。

答案 2 :(得分:0)

根据this article,使用CommonsMultipartResolver正确地制定一个多部分请求很重要,而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());

希望有帮助。

答案 3 :(得分:0)

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

@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 :(得分:0)

如果有人遇到 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;
    }
}