Spring ControllerAdvice没有捕获SizeLimitExceededException?

时间:2018-02-20 17:59:08

标签: java spring

在使用Spring的Java Web应用程序上,当我上传大于定义的最大大小的文件时,会抛出org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException

我希望它被我的自定义ExceptionHandlingController.class捕获,该@ControllerAdvice使用Caused by: org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (174470507) exceeds the configured maximum (7000000) 进行注释,并且成功捕获了我喜欢用某些特定逻辑处理的所有其他特定异常;但不是 这个

什么可能导致这种有问题的行为,我该如何解决?

例外是明确的:

applicationContext.xml

我的<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="7000000" /><!-- amount is in Bytes --> </bean>

中的最大文件大小定义如下
ExceptionHandlingController

@ControllerAdvice public class ExceptionHandlingController { private static final Logger NON_SECURITY_LOGGER = Logger.getLogger(ExceptionHandlingController.class); @ExceptionHandler({MailSendException.class}) public RedirectView handleError(HttpServletRequest req, MailSendException exception) { RedirectView rw = new RedirectView("/"); FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(req); outputFlashMap.put(Constants.FLASH_GENERIC, "Our mail service seems to have issues. Please try again or contact an administrator if the problem persists"); return rw; } // TODO THIS WON'T GET CAUGHT !!!!!!!!!!!! @ExceptionHandler({FileUploadBase.SizeLimitExceededException.class}) public RedirectView handleError(HttpServletRequest req, FileUploadBase.SizeLimitExceededException exception) { RedirectView rw = new RedirectView("/"); FlashMap outputFlashMap = RequestContextUtils.getOutputFlashMap(req); outputFlashMap.put(Constants.FLASH_GENERIC, "Woops ! The file that you tried to upload is too large. Please respect the rules."); return rw; } @ExceptionHandler({Exception.class}) public ModelAndView handleError(HttpServletRequest req, Exception exception) throws Exception { NON_SECURITY_LOGGER.log(ERROR, "######### EXCEPTION #########", exception); throw exception; }} 类,有一些修改(在SO上不能得到很好的缩进.. :):

web.xml
<filter> <async-supported>true</async-supported> <filter-name>multipartFilter</filter-name> <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class> </filter> <filter-mapping> <filter-name>multipartFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 中的

web.xml

作为奖励,如果我可以在达到最大文件大小时抛出异常,而不是在整个上传结束之后,这将是很好的;但这应该是一个单独的问题:)

注意:我确认其他处理程序未捕获该异常。它简直就是绕过&#34;一切。

感谢您的帮助! :)

===有效答复的更新/反馈===

正如Elevate在经过验证的回答中指出的那样,我只是从applicationContext.xml中删除了过滤器,并将bean配置从dispatcher-servlet.xml切换为ExceptionHandlingController(纯复制粘贴)。

此外,由于重新布线,MaxUploadSizeExceededException现在会抓住SizeLimitExceededException而不是var data={ "soapenv:Envelope":{ "soapenv:Body":{ "CaseDetails":[ { "Status":"Open", "Opened":"2018-02-19T10:56:03.783Z", "ns1:CaseReference": {"id":"111111"} }, { "Status":"Closed", "Opened":"2017-02-19T10:56:03.783Z", "ns3:CaseReference": {"id":"222222"} }, { "Status":"Closed", "Opened":"2016-02-19T10:56:03.783Z", "ns8:CaseReference": {"id":"3333"} } ] } }

现在抓住了异常;感谢Elevate的帮助!

2 个答案:

答案 0 :(得分:2)

你问:&#34;什么可能导致这种有问题的行为?&#34;

多部分过滤器正在控制器周围应用,因此控制器不会看到异常。它没有发生在控制器内部。

MultipartFilter的documentation表示它是针对您未使用Spring的Web MVC的用例而设计的:

  

注意:此过滤器是使用DispatcherServlet的MultipartResolver支持的替代方法,例如,对于具有不使用Spring的Web MVC的自定义Web视图的Web应用程序,或者在Spring MVC之前应用的自定义过滤器DispatcherServlet的。

你问,&#34;我该如何解决这个问题?&#34;

答案是(显然)将多部分处理放在控制器中。 :)

您需要从web.xml中删除过滤器,并将CommonsMultipartResolver配置为在控制器范围内运行。我不确切知道您的控制器是如何配置的,因此您必须解决或发布其他问题!

答案 1 :(得分:0)

您可以通过以下方式以编程方式创建解析程序bean:

@Configuration
@Component
public class MultipartResolverBeanConfig {

  /**
   * Create the multipart resolver bean
   * Set the maximum upload file size as defined in the configuration file
   * @return the multipartResolver bean
   */
  @Bean(name="multipartResolver")
  public CommonsMultipartResolver multipartResolver() {
    CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
    multipartResolver.setMaxUploadSize(100000);
    return multipartResolver;
  }
}

您将其更改为MaxUploadSizeExceededException是正确的,但您也可以从中获取SizeLimitExceededException

@ExceptionHandler(value = { MaxUploadSizeExceededException.class })
protected ResponseEntity<Object> handleMaxUploadSizeExceededException(Exception ex, WebRequest request) {
    MaxUploadSizeExceededException musee = (MaxUploadSizeExceededException)ex;
    SizeLimitExceededException slee = musee.getCause() instanceof SizeLimitExceededException ? (SizeLimitExceededException) musee.getCause() : null;
    Long maxSize = slee == null ? musee.getMaxUploadSize() : slee.getPermittedSize();
    Long actualSize = slee == null ? Long.parseLong(request.getHeader("Content-Length")) : slee.getActualSize();

    return handleExceptionInternal(ex, "error", new HttpHeaders(), HttpStatus.NOT_ACCEPTABLE, request);
  }