1.@RestControllerAdvice+在方法上添加@ExceptionHandler
该异常处理方式,过滤器执行完之后,在DispatcherServlet中doDispatch(...)方法中捕获到抛出的异常。异常处理的时机是处理完HandlerInterceptor.postHandle(...)之后,通过processDispatchResult方法内processHandlerException()(在异常不为null)方法处理异常。处理完异常结果交给响应体后,(有无异常)调用HandlerInterceptor.afterCompletion()方法。所以该异常处理方式处理不了过滤器抛出的异常,只能ha.handle(...)和拦截器的postHandle,preHandle抛出的异常。
//DispatcherServlet
void doDispatch(HttpServletRequest request, HttpServletResponse response)->{
//RequestMappingHandlerAdapter对象ha
try{
mv = ha.handle(processedRequest, response, mappedHandler.getHandler())->{
mappedHandler.applyPreHandle(processedRequest, response);
mav = ha.invokeHandlerMethod(request, response, handlerMethod)->{
Object returnValue = this.invokeForRequest(webRequest, mavContainer,
providedArgs)->{
try{
return this.getBridgedMethod().invoke(this.getBean(), args);
// 1.抛出异常
}catch(IllegalArgumentException var4){
throw new new IllegalStateException(...)
}catch (InvocationTargetException var5) {
Throwable targetException = var5.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException)targetException;
} else if (targetException instanceof Error) {
throw (Error)targetException;
} else if (targetException instanceof Exception) {
throw (Exception)targetException;
} else {
throw new IllegalStateException(...);
}
}
};
this.setResponseStatus(webRequest);
this.returnValueHandlers.handleReturnValue(returnValue,
this.getReturnValueType(returnValue), mavContainer, webRequest);
}
return mav;
}
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 2.如果抛出的异常 instanceof Exception,直接捕获,且将异常赋值给变量dispatchException
// instanceof Throwable,直接捕获,且new NestedServletException赋值给变量
}catch (Exception var20) {
dispatchException = var20;
}catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
// 3.处理dispatchException,处理mv
this.processDispatchResult(processedRequest, response, mappedHandler, mv,
(Exception)dispatchException)->{
//dispatchException不为null
if (exception instanceof ModelAndViewDefiningException) {
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
} else {
mv = this.processHandlerException(request, response, handler, exception)->{
// DispatcherServlet类属性
// List<HandlerExceptionResolver> handlerExceptionResolvers
// 1.handlerExceptionResolvers[0]=DefaultErrorAttributes
// DefaultErrorAttributes.resolveException() 向请求中存放该异常
// 2.handlerExceptionResolvers[1]=HandlerExceptionResolverComposite
// HandlerExceptionResolverComposite.resolvers[0]
// 为ExceptionHandlerExceptionResolver里存放ControllerAdviceBean
// HandlerExceptionResolverComposite.resolvers.
// resolveException() 循环调用,直到mav不等null结束
// 3.handlerExceptionResolvers[2]=实现HandlerExceptionResolver类
// 循环调用handlerExceptionResolvers,直到exMv不为null退出
this.handlerExceptionResolvers.iterator();
}
}
//dispatchException为null,则
this.render(mv, request, response);
// 所有拦截器的afterCompletion方法
interceptors.afterCompletion(...);
};
}