SpringBoot: 异常处理机制原理 ---- 14

ssss其实想真正学习好一门技术,应该去该技术的网站查阅一些文档去学习,比如对于异常的处理机制,我们可以去SpringBoot官网的官方文档学习。Spring Boot Features ===> 7. Developing Web Applications ===> 7.1.10. Error Handling

错误处理的默认规则

官方文档是这样说的:

ssssBy default, Spring Boot provides an /error mapping that handles all errors in a sensible way, and it is registered as a “global” error page in the servlet container.
ssss● 默认情况下,Spring Boot提供/error处理所有错误的映射。
ssssFor machine clients, it produces a JSON response with details of the error, the HTTP status, and the exception message.
ssss● 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。
在这里插入图片描述
ssssFor browser clients, there is a “whitelabel” error view that renders the same data in HTML format (to customize it, add a View that resolves to error).
ssss● 对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据。如果要对其进行自定义,需要添加View解析error。
在这里插入图片描述
ssssTo replace the default behavior completely, you can implement ErrorController and register a bean definition of that type or add a bean of type ErrorAttributes to use the existing mechanism but replace the contents.

ssss● 要完全替换默认行为,可以实现 ErrorController 并注册该类型的Bean定义,或添加ErrorAttributes类型的组件以使用现有机制但替换其内容。

ssssIf you want to display a custom HTML error page for a given status code, you can add a file to an /error directory.
ssss● error/下的4xx,5xx页面会被自动解析;

定制错误处理逻辑

ssss● 自定义错误页
ssssdsdsdsdsdasd在这里插入图片描述

自定义错误页

ssss ● error/404.html error/5xx.html;(对于客户端的异常)有精确的错误状态码页面就匹配精确,没有就找 4xx.html;如果都没有就触发白页。
在这里插入图片描述
ssss页面命名为 4xx.html:
在这里插入图片描述

@ControllerAdvice+@ExceptionHandler处理全局异常

ssss 底层是 ExceptionHandlerExceptionResolver 支持的 (三大异常解析器之一)

@ResponseStatus+自定义异常 :
@ResponseStatus(value= HttpStatus.FORBIDDEN,reason = "用户数量太多")
public class UserTooManyException extends  RuntimeException{

    public UserTooManyException(){}
    public UserTooManyException(String messages){
        super(messages);
    }
}

在这里插入图片描述
ssss 底层是 ResponseStatusExceptionResolver (三大解析之一)。把ResponseStatus注解的信息通过底层调用 response.sendError(statusCode, resolvedReason)发送(错误请求403) ==》它代表当前请求结束,并由tomcat发送的/error请求,最终适配到 4xx.html。

Spring底层的异常

ssss如 参数类型转换异常;DefaultHandlerExceptionResolver(三大异常解析器之一) 处理框架底层的异常。下图是原始的Tomat异常:
ssdsss在这里插入图片描述

自定义实现 HandlerExceptionResolver 处理异常;可以作为默认的全局异常处理规则
@Order(value = Ordered.HIGHEST_PRECEDENCE) // 优先级,数字越小,优先级越高
@Component
public class CustomedHandlerExceptionResolver  implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                         HttpServletResponse httpServletResponse,
                                         Object o, Exception e) {
        try {
            httpServletResponse.sendError(511,"自定义异常解析器");
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        return new ModelAndView();
    }
}

sdssdssss在这里插入图片描述

ErrorViewResolver 实现自定义处理异常;

ssdsss ○ response.sendError 。error请求就会转给controller

ssdsss ○ 你的异常没有任何人能处理。tomcat底层 response.sendError。error请求就会转给controller

ssdsss ○ basicErrorController 要去的页面地址是 ErrorViewResolver ;

异常处理自动配置原理

ssss ● ErrorMvcAutoConfiguration 自动配置异常处理规则

sdssdsss ○ 容器中的组件:类型:DefaultErrorAttributes -> id:errorAttributes

sdsdsdsdsss ■ public class DefaultErrorAttributes implements ErrorAttributes, HandlerExceptionResolver(通过继承关系我可以知道 DefaultErrorAttributes其实就是一个默认的异常解析器)

sdssddsdsss ■ DefaultErrorAttributes:定义错误页面中可以包含哪些数据。(下面两图还是,并且不仅仅这些,其实还有很多,如果依旧不够用,那么可以自定义)
在这里插入图片描述
在这里插入图片描述
ssss ○ 容器中的组件:类型:BasicErrorController --> id:basicErrorController(json+白页 适配响应)
ssdsdsss ■ 处理默认 /error 路径的请求;页面响应 new ModelAndView(“error”, model);
在这里插入图片描述
在这里插入图片描述
ssddssss ■ 容器中有组件 View->id是error;(响应默认错误页)
在这里插入图片描述
在这里插入图片描述
ssdsdsss[注]:容器中放组件 BeanNameViewResolver(视图解析器);按照返回的视图名作为组件的id去容器中找View对象。

ssdsdsss[注]:BasicErrorController的作用其实就是根据内容协商看返回什么类型数据,比如浏览器的就返回HTML页面,如果是客户端就返回JSON数据。

ssss ○ 容器中的组件:类型:DefaultErrorViewResolver -> id:conventionErrorViewResolver
ssdsss ■ 如果发生错误,会以HTTP的状态码 作为视图页地址(viewName),找到真正的页面 error/404、5xx.html
在这里插入图片描述
在这里插入图片描述
ssdsss [注2]: 如果想要返回页面;就会找error视图【StaticView】。(默认是一个白页)

异常处理步骤流程

ssss 1、执行目标方法,目标方法运行期间有任何异常都会被catch、而且标志当前请求结束;并且用 dispatchException .
ssss [注] :当我们在处理请求过程中,令 int i=1/0; 因此这时会出现java.lang.ArithmeticException: / by zero,所以我们在执行目标方法时,不会返回mv,而是抛出异常,且mv==null;
在这里插入图片描述
ssss 2、进入视图解析流程(页面渲染流程) ,并且当前的异常已经封装到了dispatchException中。
在这里插入图片描述
sssasss 2.1、processHandlerException()处理handler中的异常,处理完成返回 ModelAndView
在这里插入图片描述
ssdsssprocessHandlerException() 中遍历所有的 handlerExceptionResolvers,看谁能处理当前异常【HandlerExceptionResolver处理器异常解析器】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ssdsss 【注1】:系统默认的异常解析器;
在这里插入图片描述
【处理流程分析】:

dsd①、DefaultErrorAttributes先来处理异常。把异常信息保存到request域,并且返回null;

 exMv = resolver.resolveException(request, response, handler, ex);
 	=====this.storeErrorAttributes(request, ex);
 			======》
 				request.setAttribute(ERROR_ATTRIBUTE, ex);	

dsd ②、剩下的三个异常解析器默认不能处理这类的异常(和注解有关),所以这时,没有任何解析器能处理异常,所以异常会被抛出,只不过这时异常被存储到了requst中。在这里插入图片描述
sssdds ■ 1、这时,如果没有任何人能处理最终底层就会发送 /error 请求。继续deBug,会被底层的BasicErrorController处理。
在这里插入图片描述
在这里插入图片描述
sssdds ■ 2、解析错误视图;遍历所有的 ErrorViewResolver 看谁能解析。
在这里插入图片描述
sssdds ■ 3、默认的 DefaultErrorViewResolver (自动配置进去的),作用是把响应状态码作为错误页的地址,error/500.html
在这里插入图片描述
sssdds ■ 4、模板引擎最终响应这个页面 error/500.html

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值