使用SpringMVC MultipartFile上传文件,当上传文件超过限制时,使用 @ExceptionHandler 捕获了异常,但是后台仍然抛出了异常,而且前台无响应!问题有二:
1.为什么捕获的异常,又抛出了?
2.为什么响应没有返回呢?SpringMVC 的 CommonsMultipartResolver  配置与自定义的ExceptionHandlerExceptionResolver子类的配置:<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- Default is 10240, according to Commons FileUpload. -->
        <property name="maxInMemorySize" value="10240"></property>
        <!-- 临时文件目录
        <property name="uploadTempDir" value="/WEB-INF/temp"></property> -->
        <property name="defaultEncoding" value="UTF-8"/>
        <!-- 指定所上传文件的总大小不能超过10M。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
        <property name="maxUploadSize" value="5242880"/><!-- 10485760 -->
        <!-- 设置上传的单文件大小
        <property name="maxUploadSizePerFile" value="2097152"/> --><!-- 5242880 -->
        <!--resolveLazily属性启用是为了推迟文件解析,以便在 UploadController 中捕获文件大小异常 --> 
        <property name="resolveLazily" value="true"/>
    </bean>
    
    <!-- 处理适配器
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="cacheSeconds" value="0" />
<property name="messageConverters" ref="messageConverters" />
</bean> -->
<!-- Http messageConverters,用于将对象输出到客户端 -->
<util:list id="messageConverters">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json</value>
<value>application/javascript</value>
<value>text/json</value>
<value>text/javascript</value>
</list>
</property>
</bean>
</util:list>
    
<bean id="handlerExceptionResolver" class="com.*.common.exception.AnnotationHandlerMethodExceptionResolver">
<property name="defaultErrorView" value="error/exception"/>
<property name="messageConverters" ref="messageConverters"/>
</bean>
在 Controller 中定义处理异常的方法: @ExceptionHandler(Exception.class)
 @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR)
 public ModelAndView handleException(Exception ex, HttpServletRequest request) {
  System.out.println("######################### handleException capture this exception");
  return new ModelAndView().addObject("error", "错误信息");
 }

解决方案 »

  1.   

    自定义的 ExceptionHandlerExceptionResolver 子类的实现public class AnnotationHandlerMethodExceptionResolver extends ExceptionHandlerExceptionResolver {

    private String defaultErrorView;

    public String getDefaultErrorView() {
    return defaultErrorView;
    } public void setDefaultErrorView(String defaultErrorView) {
    this.defaultErrorView = defaultErrorView;
    } protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, 
    HandlerMethod handlerMethod, Exception exception) {

    if (handlerMethod == null) {
    return null;
    }

    Method method = handlerMethod.getMethod(); if (method == null) {
    return null;
    }

    ModelAndView returnValue = super.doResolveHandlerMethodException(request, response, handlerMethod, exception);

    ResponseBody responseBodyAnn = AnnotationUtils.findAnnotation(method, ResponseBody.class);
    if (responseBodyAnn != null) {
    try {
    ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(method, ResponseStatus.class);
    if (responseStatusAnn != null) {
    HttpStatus responseStatus = responseStatusAnn.value();
    String reason = responseStatusAnn.reason();
    if (!StringUtils.hasText(reason)) {
    response.setStatus(responseStatus.value());
    } else {
    try {
    response.sendError(responseStatus.value(), reason);
    } catch (IOException e) { }
    }
    }

    return handleResponseBody(returnValue, request, response);
    } catch (Exception e) {
    return null;
    }
    }

    if(returnValue.getViewName() == null){
    returnValue.setViewName(defaultErrorView);
    }

    return returnValue;

    }


    @SuppressWarnings({ "unchecked", "rawtypes" })
    private ModelAndView handleResponseBody(ModelAndView returnValue, HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException {

    Map value = returnValue.getModelMap();
    HttpInputMessage inputMessage = new ServletServerHttpRequest(request);
    List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
    if (acceptedMediaTypes.isEmpty()) {
    acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
    }
    MediaType.sortByQualityValue(acceptedMediaTypes);
    HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
    Class<?> returnValueType = value.getClass();
    List<HttpMessageConverter<?>> messageConverters = super.getMessageConverters();
    if (messageConverters != null) {
    for (MediaType acceptedMediaType : acceptedMediaTypes) {
    for (HttpMessageConverter messageConverter : messageConverters) {
    if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
    messageConverter.write(value, acceptedMediaType, outputMessage);
    return new ModelAndView();
    }
    }
    }
    }
    if (logger.isWarnEnabled()) {
    logger.warn("Could not find HttpMessageConverter that supports return type [" + returnValueType + "] and " + acceptedMediaTypes);
    }
    return null;
    }}
      

  2.   

    chrome请求内容
      

  3.   

    浏览器原因,无解,edge浏览器就可以,建议客户端增加判断超出大小直接弹出信息提醒