MaxUploadSizeExceededException不会调用Spring中的异常处理方法(M

2019-07-18 04:13发布

我使用Spring 3.2.0。 根据这个答案,我也有同样的方法在我的注解控制器,实现了HandlerExceptionResolver接口,例如,

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {

    Map<String, Object> model = new HashMap<String, Object>(0);

    if (exception instanceof MaxUploadSizeExceededException) {
        model.put("msg", exception.toString());
        model.put("status", "-1");
    } else {
        model.put("msg", "Unexpected error : " + exception.toString());
        model.put("status", "-1");
    }

    return new ModelAndView("admin_side/ProductImage");
}

和Spring配置包括,

<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize">
        <value>10000</value>
    </property>
</bean>

当文件大小超过,上述方法被调用,它会自动处理异常,但它并不发生在所有。 该方法resolveException()不会被调用,即使发生异常。 什么是处理这个异常的方式吗? 我缺少的东西吗?

同样的事情也被指定在这里 。 我不知道为什么它不会在我的情况下工作。


我曾尝试以下方法与@ControllerAdvice ,但它也不能工作。

package exceptionhandler;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public final class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {

    @ExceptionHandler(value = {MaxUploadSizeExceededException.class})
    protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request) {
        String bodyOfResponse = "This should be application specific";
        return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);
    }
}

我也曾尝试把冗长- Exception

@ExceptionHandler(value={Exception.class})

该方法ResponseEntity()是从来没有在任何情况下被调用。


在一般情况下,我想如果可能的话来处理每个控制器基地(控制器级别)此异常。 为此,一个@ExceptionHandler注解的方法只应积极针对特定的控制器,而不是全局为整个应用程序,因为只有少数的网页在我的应用程序,处理文件上传。 此异常时造成的,我只是想表明当前页面上的用户友好的错误消息,而不是重定向到配置的错误页面web.xml文件。 如果这甚至不是可行的,那么这个异常应不反正我刚才表达的任何定制要求进行处理。

无论是办法为我工作。 没有更多有关处理这个例外,我能找到。 是否需要额外的配置某处在XML文件中或以其他方式?


什么异常被抛出后,可以在下面看到我越来越快照 。

Answer 1:

根据你的贴堆栈跟踪的MaxUploadSizeExceeded请求已经达到了调度员的servlet 之前抛出异常。 因此你的ExceptionHandler不叫,因为在该点的异常被抛出的目标控制器尚未确定。

如果你看一下堆栈跟踪,你可以看到抛出异常的HiddenHttpMethodFilter ,得到您的多部分请求的所有参数- ,也是你的“变大”的上传数据参数。

HiddenHttpMethodFilter需要为您的控制器处理多上传? 如果没有,排除您的上传处理控制器,该过滤器。



Answer 2:

你可以是CommonsMultipartResolver的resolveLazily属性配置,以这样的情况:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="resolveLazily" value="true"/>
</bean>


Answer 3:

从答案张贴德克Lachowski,我已经排除其中一些被用于从多上传页面HiddenHttpMethodFilter

HiddenHttpMethodFilter原本被赋予像一个URL模式/* 。 因此,它是单调乏味的运动在一个单独的目录/文件夹这些页,并指定一个不同的URL图案像/xxx/* 。 为了避免这种情况,我继承OncePerRequestFilter在我自己的类和排除用于多上载该工作如预期显示当前页面上的用户友好的错误消息,这些网页。

package filter;

import java.io.IOException;
import java.util.Locale;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

public final class HiddenHttpMethodFilter extends OncePerRequestFilter {

    /**
     * Default method parameter: <code>_method</code>
     */
    public static final String DEFAULT_METHOD_PARAM = "_method";

    private String methodParam = DEFAULT_METHOD_PARAM;

    /**
     * Set the parameter name to look for HTTP methods.
     *
     * @see #DEFAULT_METHOD_PARAM
     */
    public void setMethodParam(String methodParam) {
        Assert.hasText(methodParam, "'methodParam' must not be empty");
        this.methodParam = methodParam;
    }

    private boolean excludePages(String page) {
        //Specifically, in my case, this many pages so far have been excluded from processing avoiding the MaxUploadSizeExceededException in this filter. One could use a RegExp or something else as per requirements.
        if (page.equalsIgnoreCase("Category.htm") || page.equalsIgnoreCase("SubCategory.htm") || page.equalsIgnoreCase("ProductImage.htm") || page.equalsIgnoreCase("Banner.htm") || page.equalsIgnoreCase("Brand.htm")) {
            return false;
        }
        return true;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        String servletPath = request.getServletPath();

        if (excludePages(servletPath.substring(servletPath.lastIndexOf("/") + 1, servletPath.length()))) {
            String paramValue = request.getParameter(this.methodParam);
            //The MaxUploadSizeExceededException was being thrown at the preceding line.
            if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
                String method = paramValue.toUpperCase(Locale.ENGLISH);
                HttpServletRequest wrapper = new filter.HiddenHttpMethodFilter.HttpMethodRequestWrapper(request, method);
                filterChain.doFilter(wrapper, response);
            } else {
                filterChain.doFilter(request, response);
            }
        } else {
            filterChain.doFilter(request, response);
        }
    }

    /**
     * Simple {@link HttpServletRequest} wrapper that returns the supplied
     * method for {@link HttpServletRequest#getMethod()}.
     */
    private static class HttpMethodRequestWrapper extends HttpServletRequestWrapper {

        private final String method;

        public HttpMethodRequestWrapper(HttpServletRequest request, String method) {
            super(request);
            this.method = method;
        }

        @Override
        public String getMethod() {
            return this.method;
        }
    }
}

而在我web.xml文件中,此过滤器- filter.HiddenHttpMethodFilter指定的,而不是org.springframework.web.filter.HiddenHttpMethodFilter如下。

<filter>
    <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>

<filter>
    <filter-name>httpMethodFilter</filter-name>
    <filter-class>filter.HiddenHttpMethodFilter</filter-class>
    <!--<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> This was removed replacing with the preceding one-->
</filter>
<filter-mapping>
    <filter-name>httpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

我仍然希望有应该/可能是处理问题的异常,并沿着公平的方式org.springframework.web.filter.HiddenHttpMethodFilter



Answer 4:

您@ExcpetionHandler不工作,因为这些注释的方法只能返回类型的ModelAndView或字符串,从我记得。 请参阅此公告的更多细节。



Answer 5:

我的解决方案:一是为实现HandlerExceptionResolver类中定义的bean。

 <bean id="classForBeanException" class="XXXX.path.To.classForBeanException" />


Answer 6:

在您的ControllerAdvice正在处理异常,你可以有这样的代码this.It工作了me.This在春天4.0+

@ExceptionHandler(Exception.class)
public @ResponseBody BaseResponse onException(Exception e, HttpServletResponse response) {
    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

    BaseResponse resp = new BaseResponse();
    if(e instanceof MaxUploadSizeExceededException){
        resp.setCode(FileUploadFailed.SIZE_EXCEED);
        resp.setMessage("Maximum upload size exceeded");
    }
    return resp;
}


文章来源: MaxUploadSizeExceededException doesn't invoke the exception handling method in Spring