首页 > spring-mvc如何优雅的处理异常

spring-mvc如何优雅的处理异常

目前正在学习spring mvc,遇到两个问题,在此请教各位大神:

1、异常处理部分一般通过实现 org.springframework.web.servlet.HandlerExceptionResolver 来统一处理,但是:

以上类型的异常会被 org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver 处理掉,但是返回了我不希望的结果。

如图:由于 order 不够优先,提前弹出结果了!

请教下各位,这类问题是如何统一所有类型的异常的?目前我的理解是

@Override
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {

    int statusCode = 0;
    boolean found = true;

    try {
        if (ex instanceof NoSuchRequestHandlingMethodException) {
            statusCode = HttpServletResponse.SC_NOT_FOUND;
        } else if (ex instanceof HttpRequestMethodNotSupportedException) {
            statusCode = HttpServletResponse.SC_METHOD_NOT_ALLOWED;
        } else if (ex instanceof HttpMediaTypeNotSupportedException) {
            statusCode = HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
        } else if (ex instanceof HttpMediaTypeNotAcceptableException) {
            statusCode = HttpServletResponse.SC_NOT_ACCEPTABLE;
        } else if (ex instanceof MissingServletRequestParameterException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof ServletRequestBindingException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof ConversionNotSupportedException) {
            statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
        } else if (ex instanceof TypeMismatchException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof HttpMessageNotReadableException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof HttpMessageNotWritableException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof MethodArgumentNotValidException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof MissingServletRequestPartException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof BindException) {
            statusCode = HttpServletResponse.SC_BAD_REQUEST;
        } else if (ex instanceof NoHandlerFoundException) {
            statusCode = HttpServletResponse.SC_NOT_FOUND;
        } else {
            found = false;
        }

        if (found) {
            ServiceException error = new ServiceException(statusCode, "Forbidden");
            error.setException(ex);

            ex = error;
        }
    } catch (Exception e) {

    }
    return super.processHandlerException(request, response, handler, ex);
}

求助!


2、第二个问题,我希望对 JSON 请求返回JSON错误,例如:

{
    "status": 500,
    "statusInfo": "Internal Server Error",
    "data": {
        "type": "Exception",
        "message": "UserException"
    }
}

但是异常处理方法 resolveException(HttpServletRequest request, HttpServletResponse response, Object obj, Exception ex) 中无法确定该请求到底该由哪个 View 渲染啊

我的理解:


PS:Java初学者,大神勿喷


第一个问题找到方法了:

<bean class="org.springframework.web.servlet.handler.HandlerExceptionResolverComposite">
    <property name="order" value="0" />
    <property name="exceptionResolvers">
        <list>
            <bean class="io.conf.DefaultExceptionResolver">
                <property name="errorView" value="/common/error" />
                <property name="showErrorState" value="false" />
            </bean>
        </list>
    </property>
</bean>
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    if (ex == null) {
        return null;
    }
    ModelAndView mv;
    try {

        // 判断是不是异步请求
        if (WebUtils.hasResponseAnnotation(handler)) {
            mv = new ModelAndView(new JsonView());
            if (showErrorState) {
                response.sendError(500);
            }
        } else {
            mv = new ModelAndView(errorView);
        }

        int statusCode = 500;

        try {
            if (ex instanceof NoSuchRequestHandlingMethodException) {
                statusCode = HttpServletResponse.SC_NOT_FOUND;
            } else if (ex instanceof HttpRequestMethodNotSupportedException) {
                statusCode = HttpServletResponse.SC_METHOD_NOT_ALLOWED;
            } else if (ex instanceof HttpMediaTypeNotSupportedException) {
                statusCode = HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
            } else if (ex instanceof HttpMediaTypeNotAcceptableException) {
                statusCode = HttpServletResponse.SC_NOT_ACCEPTABLE;
            } else if (ex instanceof MissingServletRequestParameterException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof ServletRequestBindingException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof ConversionNotSupportedException) {
                statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
            } else if (ex instanceof TypeMismatchException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof HttpMessageNotReadableException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof HttpMessageNotWritableException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof MethodArgumentNotValidException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof MissingServletRequestPartException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof BindException) {
                statusCode = HttpServletResponse.SC_BAD_REQUEST;
            } else if (ex instanceof NoHandlerFoundException) {
                statusCode = HttpServletResponse.SC_NOT_FOUND;
            }
        } catch (Exception e) {

        }

        Map<String, Object> data = new HashMap<String, Object>();
        data.put("message", ex.getMessage());
        data.put("type", ex.getClass().getSimpleName());

        mv.addObject("status", statusCode);
        mv.addObject("data", data);
        mv.addObject("statusInfo", ex.getLocalizedMessage());

        return mv;

    } catch (Exception e) {

    }

    return null;
}

@ControllerAdvice+@ExceptionHandler 解决你的第二个问题,第一个问题是代码设计上的问题,跟spring关系不大。

【热门文章】
【热门文章】