第十章 Spring5异常与跨域问题笔记

一、异常处理分析1、Controller调用过程中的异常解析使用示例代码如下:package com.chj.controllerAdvice;@ControllerAdvice("com.chj")public class ExceptionHandlerControllerAdvice {@ExceptionHandler({ArrayIndexOutOfBoundsEx...
摘要由CSDN通过智能技术生成

一、异常处理分析

1、Controller调用过程中的异常解析使用

示例代码如下:package com.chj.controllerAdvice;

@ControllerAdvice("com.chj")
public class ExceptionHandlerControllerAdvice {
    @ExceptionHandler({ArrayIndexOutOfBoundsException.class})
    public @ResponseBody String handlerArrayIndexOutOfBoundsException(Exception e) {
        System.out.println("====ExceptionHandlerControllerAdvice-->" + e.getMessage());
        return "ArrayIndexOutOfBoundsException";
    }
    @ExceptionHandler({NullPointerException.class})
    public @ResponseBody String handlerNullPointerException(Exception e) {
        System.out.println("====ExceptionHandlerControllerAdvice-->" + e.getMessage());
        return "NullPointerException";
    }
}

类上面加上@ControllerAdvice("com.chj")注解,这个包定义就是只对这个包里面的Controller生效。然后类里面的方法加上@ExceptionHandler({ArrayIndexOutOfBoundsException.class})与@ExceptionHandler 

({NullPointerException.class})。

表示这个方法当调用过程中出现注解里面定义的异常时会被调用到,这些方法就是对异常处理的方法。

源码的核心思想差不多

1)收集注解包装成类;

2)建立@ExceptionHandler中异常和Method的映射关系;

3)根据出现的异常从映射关系中找到对应的Method对象;

4)反射调用,这个调用逻辑跟Controller里面具体方法调用逻辑一模一样。

2、异常源码分析

2.1、异常处理源码入口

org.springframework.web.servlet.DispatcherServlet#doDispatch

catch (Exception ex) {
   dispatchException = ex;
}

catch (Throwable err) {
   // As of 4.3, we're processing Errors thrown from handler methods as well,
   // making them available for @ExceptionHandler methods and other scenarios.
   dispatchException = new NestedServletException("Handler dispatch failed", err);
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

如果exception不为空,进行异常处理

org.springframework.web.servlet.DispatcherServlet#processDispatchResult

private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
      @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
      @Nullable 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);
      }
   }

org.springframework.web.servlet.DispatcherServlet#processHandlerException

@Nullable
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response,
      @Nullable Object handler, Exception ex) throws Exception {
   // Success and error responses may use different content types
   request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
   // Check registered HandlerExceptionResolvers...
   ModelAndView exMv = null;
   if (this.handlerExceptionResolvers != null) {
      for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
         exMv = resolver.resolveException(request, response, handler, ex);
         if (exMv != null) {
            break;
         }
      }
   }

2.2、异常处理抽象方法逻辑处理

该方法最终还是会调用到抽象类里面的resolveException方法:

org.springframework.web.servlet.handler.HandlerExceptionResolverComposite#resolveException

@Override
@Nullable
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
      @Nullable Object handler,Exception ex) {
   if (this.resolvers != null) {
      for (HandlerExceptionResolver handlerExceptionResolver : this.resolvers) {
         ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex);
         if (mav != null) {
            return mav;
         }
      }
   }
   return null;
}

异常处理抽象方法代码如下:

org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver#resolveException

 

org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver#doResolveException

@Override
@Nullable
protected final ModelAndView doResolveException(
      HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {
   return doResolveHandlerMethodException(request, response, (HandlerMethod) handler, ex);
}

org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException

protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,
      HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {
   ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
   if (exceptionHandlerMethod == null) {
      return null;
   }
   if (this.argumentResolvers

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值