【问题标题】:Cannot configure CommonsMultipartResolver with Spring Boot 1.2.8无法使用 Spring Boot 1.2.8 配置 CommonsMultipartResolver
【发布时间】:2016-08-17 14:14:45
【问题描述】:

我正在尝试在我的 Spring Boot 应用程序中使用 CommonsMultipartResolver。我不能使用StandardServletMultipartResolver,因为我想处理异常(例如超过文件大小)。

我已经建立了对commons-fileupload 的依赖。我的弹簧配置是:

    @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

否则,我得到一个异常,即请求中不存在 part 参数。

我认为我需要禁用 servlet 3.0 处理多部分请求,但我不知道如何在 Spring Boot 中执行此操作。

【问题讨论】:

  • 从堆栈跟踪来看,您似乎正在使用您在任何地方都没有提到的 Jetty。为避免任何其他差异,您能否提供一个重现问题的最小示例?

标签: spring spring-boot multipartform-data servlet-3.0 apache-commons-fileupload


【解决方案1】:

问题是由DefaultMultipartHttpServletRequestgetParameter 上抛出异常引起的,该异常由HiddenHttpMethodFilter 调用,因为流已在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 建议返回正确的 HTTP 代码。

【讨论】:

    【解决方案2】:

    Spring boot 自动配置一个 MultipartConfigElement,参见 https://spring.io/guides/gs/uploading-files/ 只需从类路径中删除 commons-fileupload

    请注意,HiddenHttpMethodFilter 需要在多部分处理后执行,如 spring 文档中所述:

    注意:在多部分 POST 请求的情况下,此过滤器需要在多部分处理之后运行,因为它固有地需要检查 POST 正文参数。因此,通常情况下,在 web.xml 过滤器链中的此 HiddenHttpMethodFilter 之前放置一个 Spring MultipartFilter。

    【讨论】:

    • 我已禁用自动配置并明确声明我不想使用StandardServletMultipartResolver
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 2016-03-03
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    • 2013-11-01
    • 2021-05-30
    相关资源
    最近更新 更多