无法使用 Spring Boot 1.2.8 配置 CommonsMultipartResolver
Cannot configure CommonsMultipartResolver with Spring Boot 1.2.8
我正在尝试在我的 Spring 启动应用程序中使用 CommonsMultipartResolver
。我不能使用 StandardServletMultipartResolver
,因为我想处理异常(例如超过文件大小)。
我已经建立了对 commons-fileupload
的依赖。我的 spring 配置是:
@Autowired
private MultipartProperties multipartProperties = new MultipartProperties();
@Bean
public MultipartConfigElement multipartConfigElement() {
return this.multipartProperties.createMultipartConfig();
}
@Bean
public MultipartResolver multipartResolver() {
LOG.debug("initializing MultipartResolver");
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
return multipartResolver;
}
@Bean
public FilterRegistrationBean multipartFilterRegistrationBean() {
final MultipartFilter multipartFilter = new MultipartFilter();
final FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(multipartFilter);
multipartFilter.setMultipartResolverBeanName("multipartResolver");
filterRegistrationBean.setOrder(OrderedHiddenHttpMethodFilter.DEFAULT_ORDER-1);
return filterRegistrationBean;
}
当我设置 MultipartFilter
在 HiddenHttpMethodFilter
之前执行时,我得到一个 IOException
:
Caused by: java.io.IOException: Missing content for multipart request
at org.eclipse.jetty.util.MultiPartInputStreamParser.parse(MultiPartInputStreamParser.java:491)
at org.eclipse.jetty.util.MultiPartInputStreamParser.getParts(MultiPartInputStreamParser.java:400)
at org.eclipse.jetty.server.Request.getParts(Request.java:2139)
at org.eclipse.jetty.server.Request.extractMultipartParameters(Request.java:385)
... 35 common frames omitted
否则,我会收到请求中不存在零件参数的异常。
我认为我需要禁用 servlet 3.0 对多部分请求的处理,但我不知道如何在 spring 启动时执行此操作。
Spring 启动自动配置一个 MultipartConfigElement,参见 https://spring.io/guides/gs/uploading-files/ 只需从类路径中删除 commons-fileupload
请注意,HiddenHttpMethodFilter 需要在多部分处理后执行,如 spring 文档所述:
NOTE: This filter needs to run after multipart processing in case of a multipart POST request, due to its inherent need for checking a POST body parameter. So typically, put a Spring MultipartFilter before this HiddenHttpMethodFilter in your web.xml filter chain.
问题是由 DefaultMultipartHttpServletRequest
在 HiddenHttpMethodFilter
调用的 getParameter
上抛出异常引起的,因为流已在 MultipartFilter
中处理:
@Override
protected void doFilterInternal(HttpServletRequest request, >HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String paramValue = request.getParameter(this.methodParam);
if ("POST".equals(request.getMethod()) && >StringUtils.hasLength(paramValue)) {
String method = paramValue.toUpperCase(Locale.ENGLISH);
HttpServletRequest wrapper = new >HttpMethodRequestWrapper(request, method);
filterChain.doFilter(wrapper, response);
}
else {
filterChain.doFilter(request, response);
}
}
我的解决方案是禁用 MultipartAutoConfiguration
,不定义 MultipartConfigElement
bean 以禁用 servlet 3.0 多部分解析并且不使用 MultipartFiler
.
现在的配置如下所示:
@Autowired
private MultipartProperties multipartProperties = new MultipartProperties();
@Bean
public MultipartResolver multipartResolver() {
LOG.debug("initializing MultipartResolver");
MultipartConfigElement config = multipartProperties.createMultipartConfig();
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setResolveLazily(true);
multipartResolver.setMaxUploadSize(config.getMaxRequestSize());
multipartResolver.setMaxUploadSizePerFile(config.getMaxFileSize());
return multipartResolver;
}
现在甚至可以在文件超过允许的最大大小时使用@ExceptionHandler 建议return 正确的 HTTP 代码。
我正在尝试在我的 Spring 启动应用程序中使用 CommonsMultipartResolver
。我不能使用 StandardServletMultipartResolver
,因为我想处理异常(例如超过文件大小)。
我已经建立了对 commons-fileupload
的依赖。我的 spring 配置是:
@Autowired
private MultipartProperties multipartProperties = new MultipartProperties();
@Bean
public MultipartConfigElement multipartConfigElement() {
return this.multipartProperties.createMultipartConfig();
}
@Bean
public MultipartResolver multipartResolver() {
LOG.debug("initializing MultipartResolver");
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
return multipartResolver;
}
@Bean
public FilterRegistrationBean multipartFilterRegistrationBean() {
final MultipartFilter multipartFilter = new MultipartFilter();
final FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(multipartFilter);
multipartFilter.setMultipartResolverBeanName("multipartResolver");
filterRegistrationBean.setOrder(OrderedHiddenHttpMethodFilter.DEFAULT_ORDER-1);
return filterRegistrationBean;
}
当我设置 MultipartFilter
在 HiddenHttpMethodFilter
之前执行时,我得到一个 IOException
:
Caused by: java.io.IOException: Missing content for multipart request
at org.eclipse.jetty.util.MultiPartInputStreamParser.parse(MultiPartInputStreamParser.java:491)
at org.eclipse.jetty.util.MultiPartInputStreamParser.getParts(MultiPartInputStreamParser.java:400)
at org.eclipse.jetty.server.Request.getParts(Request.java:2139)
at org.eclipse.jetty.server.Request.extractMultipartParameters(Request.java:385)
... 35 common frames omitted
否则,我会收到请求中不存在零件参数的异常。
我认为我需要禁用 servlet 3.0 对多部分请求的处理,但我不知道如何在 spring 启动时执行此操作。
Spring 启动自动配置一个 MultipartConfigElement,参见 https://spring.io/guides/gs/uploading-files/ 只需从类路径中删除 commons-fileupload
请注意,HiddenHttpMethodFilter 需要在多部分处理后执行,如 spring 文档所述:
NOTE: This filter needs to run after multipart processing in case of a multipart POST request, due to its inherent need for checking a POST body parameter. So typically, put a Spring MultipartFilter before this HiddenHttpMethodFilter in your web.xml filter chain.
问题是由 DefaultMultipartHttpServletRequest
在 HiddenHttpMethodFilter
调用的 getParameter
上抛出异常引起的,因为流已在 MultipartFilter
中处理:
@Override protected void doFilterInternal(HttpServletRequest request, >HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String paramValue = request.getParameter(this.methodParam); if ("POST".equals(request.getMethod()) && >StringUtils.hasLength(paramValue)) { String method = paramValue.toUpperCase(Locale.ENGLISH); HttpServletRequest wrapper = new >HttpMethodRequestWrapper(request, method); filterChain.doFilter(wrapper, response); } else { filterChain.doFilter(request, response); } }
我的解决方案是禁用 MultipartAutoConfiguration
,不定义 MultipartConfigElement
bean 以禁用 servlet 3.0 多部分解析并且不使用 MultipartFiler
.
现在的配置如下所示:
@Autowired
private MultipartProperties multipartProperties = new MultipartProperties();
@Bean
public MultipartResolver multipartResolver() {
LOG.debug("initializing MultipartResolver");
MultipartConfigElement config = multipartProperties.createMultipartConfig();
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setResolveLazily(true);
multipartResolver.setMaxUploadSize(config.getMaxRequestSize());
multipartResolver.setMaxUploadSizePerFile(config.getMaxFileSize());
return multipartResolver;
}
现在甚至可以在文件超过允许的最大大小时使用@ExceptionHandler 建议return 正确的 HTTP 代码。