异常处理
默认规则:
默认情况下,Spring Boot提供/error
处理所有错误的映射
1)对于机器客户端,如postman,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。
2)对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
源码解析:
1、DispatcherServlet.class.class
此处抛出异常
异常被捕获
进入视图解析页面渲染流程
处理handler发生的异常,处理完成返回ModelAndView
遍历所有的 handlerExceptionResolvers,看谁能处理当前异常
系统默认异常解析器有以下几种,实现自HandlerExceptionResolver
1)DefaultErrorAttributes先来处理异常。把异常信息保存到request域,并且永远返回null
2)ExceptionHandlerExceptionResolve,处理使用@ExceptionHandle自定义异常
3)ResponseStatusExceptionResolver,处理使用@ResponseStatus自定义异常
4)DefaultHandlerExceptionResolver
注意
:如果上述异常解析器为空,则遍历下一个,否则停止循环。系统默认没有任何异常解析器能处理异常,所以异常会被抛出,最终底层就会再一次发送/error
请求,然后会被底层的BasicErrorController
处理
执行目标方法
2、BasicErrorController.class
解析错误视图
3、AbstractErrorController.class
遍历所有的 ErrorViewResolver 看谁能解析。
4、DefaultErrorViewResolver.class
默认的 DefaultErrorViewResolver ,作用是把响应状态码作为错误页的地址,error/500.html ,模板引擎最终响应这个页面 error/500.html
自定义错误处理逻辑
1、ExceptionHandlerExceptionResolver
@ControllerAdvice+@ExceptionHandler自定义处理全局异常;底层是ExceptionHandlerExceptionResolver支持的
@S1f4j
@ControllerAdvice
public class MyExceptionHandler{
@ExceptionHandler(ArithmeticException.class)
public void myException(Throwable ex){
log.error("异常是:{0, {}",ex);
}
}
2、ResponseStatusExceptionResolver
@ResponseStatus+自定义异常 ;底层是ResponseStatusExceptionResolver ,把responsestatus注解的信息底层调用 response.sendError(statusCode, resolvedReason);tomcat发送的/error
@Responpestatus(value= HttpStatus.FORBIDDEN,reason = "用户数量太多")
public class UserTooManyException extends RuntimeException {
public UserTooManyException() {
}
public UserTooManyException(String message) {
super(message);
}
}
3、DefaultHandlerExceptionResolver
处理框架底层的异常,如 参数类型转换异常
4、自定义实现 HandlerExceptionResolver 处理异常,可以作为默认
的全局异常处理规则
@Order(value = Ordered.HIGHEST_PRECEDENCE)
@component
public class myHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
try {
response.sendError(555, "我的错误");
} catch (IOException e) {
e.printStackTrace();
}
return new ModelAndView();
}
}
注意
:一定要加上@order注解提高优先级,要不然顶层先执行别的异常解析器
5、自定义错误页
如,error/4xx.html;error/5xx.html;有精确的错误状态码页面就匹配精确,没有就找 5xx.html;如果都没有就触发白页