一、源码分析
processDispatchResult(…, (Exception)dispatchException):之前目标方法执行出现的异常也会作为参数传入这个方法。
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) {
this.logger.debug("ModelAndViewDefiningException encountered", exception);
mv = ((ModelAndViewDefiningException)exception).getModelAndView();
} else {
Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
mv = this.processHandlerException(request, response, handler, exception); //处理异常
errorView = mv != null;
}
}
...
}
protected ModelAndView processHandlerException(HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) throws Exception {
request.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
ModelAndView exMv = null;
if (this.handlerExceptionResolvers != null) {
Iterator var6 = this.handlerExceptionResolvers.iterator();
while(var6.hasNext()) {
HandlerExceptionResolver resolver = (HandlerExceptionResolver)var6.next();
exMv = resolver.resolveException(request, response, handler, ex);
if (exMv != null) {
break;
}
}
}
if (exMv != null) {
if (exMv.isEmpty()) {
request.setAttribute(EXCEPTION_ATTRIBUTE, ex);
return null;
} else {
if (!exMv.hasView()) {
String defaultViewName = this.getDefaultViewName(request);
if (defaultViewName != null) {
exMv.setViewName(defaultViewName);
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Using resolved error view: " + exMv, ex);
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using resolved error view: " + exMv);
}
WebUtils.exposeErrorRequestAttributes(request, ex, this.getServletName());
return exMv;
}
} else {
throw ex;
}
}
二、异常处理实例
1、本类的异常处理(本类的异常处理方法只能处理本类中发生的异常)
控制器代码:
@Controller
public class TestExceptionController {
@RequestMapping("/ex")
public String test() {
int i = 10 / 0;
return "resp";
}
@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView catex(Exception e) { //value指定具体的异常类
System.out.println(e);
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("exception", e);
return modelAndView;
}
}
error.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Error</title>
</head>
<body>
<h2>出错了!</h2>
<h2>出错信息: ${exception}</h2>
</body>
</html>
测试结果:
2、全局异常处理(可以处理所有的异常,多个异常处理方法按照精确优先的原则)
全局类:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView catex(Exception e) { //value指定具体的异常类
System.out.println(e);
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("exception", e);
return modelAndView;
}
}
测试结果: