• springmvc异常处理


    Spring MVC 通过 HandlerExceptionResolver  处理程序的异常,包括 Handler 映射、数据绑定以及目标方法执行时发生的异常。

    SpringMVC 提供的 HandlerExceptionResolver 的实现类

    DispatcherServlet  默认装配的 HandlerExceptionResolver

    ①     使用了 <mvc:annotation-driven/> 配置

    1.    ExceptionHandlerExceptionResolver

    1)主要处理 Handler 中用 @ExceptionHandler 注解定义的方法

    2)@ExceptionHandler 注解定义的方法优先级问题:例如发生的是NullPointerException,但是声明的异常有 RuntimeException 和 Exception,此候会根据异常的最近继承关系找到继承深度最浅的那个 @ExceptionHandler 注解方法,即标记了 RuntimeException 的方法

    3)ExceptionHandlerMethodResolver 内部若找不到@ExceptionHandler 注解的话,会找 @ControllerAdvice 中的@ExceptionHandler 注解方法

    2.    异常处理_ResponseStatusExceptionResolver

    3.    异常处理_DefaultHandlerExceptionResolver

    对一些特殊的异常进行处理,比如:

    NoSuchRequestHandlingMethodException、

    HttpRequestMethodNotSupportedException

    HttpMediaTypeNotSupportedException、

    HttpMediaTypeNotAcceptableException等。

    4.    异常处理_SimpleMappingExceptionResolver

    如果希望对所有异常进行统一处理,可以使用 SimpleMappingExceptionResolver,它将异常类名映射为视图名,即发生异常时使用对应的视图报告异常

    <!--简单异常映射解析器,对于用户 名存在throw的异常进行映射跳转到指定视图  -->
        <bean id="SimpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <!-- key属性是异常类型 -->
                <!-- 标签体配置目标视图 -->
                <props>
                    <prop key="com.lamsey.survey.e.UserNameAlreadyExistException">guest/user_regist</prop>
                </props>        
            </property>
        </bean>

     源码分析:

    首先springmvc核心流程如下:

    四步:
    1)、所有请求进来都经过DispatcherServlet的900:doDispatch()方法(包含了处理请求以及响应的所有流程)
    2)、916;getHandler(processedRequest);根据当前请求获取到能处理这个请求的Controller对象
    3)、923:找到能执行这个Controller对象里面每一个方法的适配器
    4)、945:ha.handle适配器调用目标方法(利用反射调用方法)
    5)、959:转发到页面(处理响应结果)processDispatchResult
    异常处理在processDispatchResult()
    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
                HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
    
            boolean errorView = false;
    
            if (exception != null) {
                if (exception instanceof ModelAndViewDefiningException) {
                    logger.debug("ModelAndViewDefiningException encountered", exception);
                    mv = ((ModelAndViewDefiningException) exception).getModelAndView();
                }
                else {
                    Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
                   //处理异常
                    mv = processHandlerException(request, response, handler, exception);
                    errorView = (mv != null);
                }
            }
    
            // Did the handler return a view to render?
            if (mv != null && !mv.wasCleared()) {
              //这是正常的页面渲染流程
                render(mv, request, response);
                if (errorView) {
                    WebUtils.clearErrorRequestAttributes(request);
                }
            }
            else {
                if (logger.isDebugEnabled()) {
                    logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
                            "': assuming HandlerAdapter completed request handling");
                }
            }
    
            if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
                // Concurrent handling started during a forward
                return;
            }
    
            if (mappedHandler != null) {
                mappedHandler.triggerAfterCompletion(request, response, null);
            }
        }

    1)判断有无异常

    //处理异常
                    mv = processHandlerException(request, response, handler, exception);

    2)对视图进行渲染

     //这是正常的页面渲染流程
                render(mv, request, response);

    遍历获取异常处理解析器

    protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
                Object handler, Exception ex) throws Exception {
    
            // Check registered HandlerExceptionResolvers...
            ModelAndView exMv = null;
    
            for (HandlerExceptionResolver handlerExceptionResolver : this.handlerExceptionResolvers) {
                exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
                if (exMv != null) {
                    break;
                }
            }
            if (exMv != null) {
                if (exMv.isEmpty()) {
                    return null;
                }
                // We might still need view name translation for a plain error model...
                if (!exMv.hasView()) {
                    exMv.setViewName(getDefaultViewName(request));
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);
                }
                WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
                return exMv;
            }
    
            throw ex;
        }
    SpringMVC默认定制页面的异常如下;
    try {
                if (ex instanceof NoSuchRequestHandlingMethodException) {
                    return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response,
                            handler);
                }
                else if (ex instanceof HttpRequestMethodNotSupportedException) {
                    return handleHttpRequestMethodNotSupported((HttpRequestMethodNotSupportedException) ex, request,
                            response, handler);
                }
                else if (ex instanceof HttpMediaTypeNotSupportedException) {
                    return handleHttpMediaTypeNotSupported((HttpMediaTypeNotSupportedException) ex, request, response,
                            handler);
                }
                else if (ex instanceof HttpMediaTypeNotAcceptableException) {
                    return handleHttpMediaTypeNotAcceptable((HttpMediaTypeNotAcceptableException) ex, request, response,
                            handler);
                }
                else if (ex instanceof MissingServletRequestParameterException) {
                    return handleMissingServletRequestParameter((MissingServletRequestParameterException) ex, request,
                            response, handler);
                }
                else if (ex instanceof ServletRequestBindingException) {
                    return handleServletRequestBindingException((ServletRequestBindingException) ex, request, response,
                            handler);
                }
                else if (ex instanceof ConversionNotSupportedException) {
                    return handleConversionNotSupported((ConversionNotSupportedException) ex, request, response, handler);
                }
                else if (ex instanceof TypeMismatchException) {
                    return handleTypeMismatch((TypeMismatchException) ex, request, response, handler);
                }
                else if (ex instanceof HttpMessageNotReadableException) {
                    return handleHttpMessageNotReadable((HttpMessageNotReadableException) ex, request, response, handler);
                }
                else if (ex instanceof HttpMessageNotWritableException) {
                    return handleHttpMessageNotWritable((HttpMessageNotWritableException) ex, request, response, handler);
                }
                else if (ex instanceof MethodArgumentNotValidException) {
                    return handleMethodArgumentNotValidException((MethodArgumentNotValidException) ex, request, response, handler);
                }
                else if (ex instanceof MissingServletRequestPartException) {
                    return handleMissingServletRequestPartException((MissingServletRequestPartException) ex, request, response, handler);
                }
                else if (ex instanceof BindException) {
                    return handleBindException((BindException) ex, request, response, handler);
                }
                else if (ex instanceof NoHandlerFoundException) {
                    return handleNoHandlerFoundException((NoHandlerFoundException) ex, request, response, handler);
                }
            }
            catch (Exception handlerException) {
                logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);
            }
            return null;
        }
  • 相关阅读:
    java oop第09章_JDBC02(CRUD操作)
    java 与日期转换相关的方法(java.util.date类型和java.sql.date类型互相转换)、随机字符串生成方法、UUID生产随机字符串
    Java oop第08章_JDBC01(入门)
    java 数组中的数值反转输出
    java oop第07章_集合框架
    Java oop创建自定义异常
    java oop遍历List和Map的几种方法
    java oop第06章_异常处理
    Java oop第05章_多态、接口
    信开发 新浪SAE开发平台 验证Token 一直失败
  • 原文地址:https://www.cnblogs.com/limingxian537423/p/7391550.html
Copyright © 2020-2023  润新知