1、异常处理
SpringMVC通过HandlerExceptionResolver处理程序的异常,包括Handler映射、数据绑定以及目标方法执行时发生的异常。
默认是这三个处理器
ExceptionHandlerExceptionResolver:@ExceptionHandler
ResponseStatusExceptionResolver:@ResponseStatus:自定义异常注解
DefaultHandlerExceptionResolver:判断是否是SpringMVC自带的异常
如果处理过程中有异常在执行完mv = ha.handle(processedRequest, response, mappedHandler.getHandler());后不会执行
applyDefaultViewName(request, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);
在catch内执行processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
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);
}
}
在mv = processHandlerException(request, response, handler, exception);这个方法里会遍历所有解析器,解析不到就是NULL,如果没有一个可以解析这个错误会throw出去,交给tomcat来处理。
2、@ExceptionHandler注解
1、在方法上给注解ExceptionHandler,告诉SpringMVC这个方法专门处理这个类发生的异常,value指的是处理的异常类,可以直接写Exception.class
2、给方法上写一个Exception,用来接收发生的异常
3、携带异常补信息不能给参数位置写Model
4、new 一个ModelAndView携带异常参数以及要转到的地址即可
5、最后return出去ModelAndView
6、有多个ExceptionHandler都能处理异常,精确优先
在每个类上都加异常方法会比较麻烦,所以将异常处理抽出一个类来。
3、抽成异常类
1、在类上标记@ControllerAdvice:告诉SpringMVC这是专门处理异常的类
2、如果本类和抽出的异常类都可以处理,本类的异常处理方法优先,处理不了再由别的处理
4、@ResponseStatus注解
1、新建一个异常类,在类上标上注解@ResponseStatus,携带reason和value,reason是错误信息提示,value是状态码
2、在处理方法上可以通过throw一个标注了ResponseStatus的类来显示自定义异常页面
5、DefaultHandlerExceptionResolver
1、例如在页面上发出一个test01的GET请求,在处理方法处没有写GET方法,写了一个POST方法,就会抛出异常,此异常就是SpringMVC自己的异常如果前两者都没人处理,则交给DefaultHandlerExceptionResolver来处理