当我在 Spring Boot 应用程序中使用 CommonsMultipartResolver 时,MultipartFile 为空
Posted
技术标签:
【中文标题】当我在 Spring Boot 应用程序中使用 CommonsMultipartResolver 时,MultipartFile 为空【英文标题】:MultipartFile is null when I use CommonsMultipartResolver in my Spring Boot app 【发布时间】: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 的配置。如何设置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 文件
它抛出一个异常:'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,因此情况可能不一样。评论不是解决问题的正确地方;如果这个问题没有帮助,请提出一个新问题。
【参考方案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)
这对我有用。
【讨论】:
以上是关于当我在 Spring Boot 应用程序中使用 CommonsMultipartResolver 时,MultipartFile 为空的主要内容,如果未能解决你的问题,请参考以下文章
带有 Docker 的 Spring Boot 2.3。当我在同一个存储库中有多个 Spring Boot 应用程序时,我想为特定应用程序构建映像
Spring Boot 轮播全屏 html,css,bootstrap
Spring Boot - 当我调用 API 时,它给出 404 错误
不支持请求方法“OPTIONS”-Spring Boot 应用程序
如何在 Spring Boot 中测试 CORS?当我在 MockMvcBuilders 中尝试时,尽管 Origin 错误,它总是返回 200