【springboot异常处理】

这里写自定义目录标题

1,Java Servlet规范

异常处理

在web.xml中定义Exception和error-code的映射。

复制代码
<!-- 根据状态码配置 -->
<error-page> 
    <error-code>404</error-code>          
    <location>/404.html</location>
</error-page>

<!-- 状态码为0时可以匹配所有的状态码 -->
<error-page> 
    <error-code>0</error-code>          
    <location>/error.html</location>
</error-page>

<!-- 根据异常类型配置 -->
<error-page> 
    <exception-type>java.lang.NullPointerException</exception-type>          
    <location>/error.html</location>
</error-page>
触发异常

HttpServletResponse.setError();

HttpServletResponse.sendError(status,msg);

2,tomcat 异常处理实现

tomcat请求处理流程
  1. 线程模型

  2. 请求处理流程

异常发生时核心处理类

当异常发生时,首先在StandardHostValve 中匹配,匹配的规则是

  1. 先根据Exception去找错误页面
  2. 再根据code去找错误页面

找到对应的页面后,dispatch到相应的页面,返回给前端进行展示。

如果没有匹配到相应的页面,tomcat使用以下两种Value进行异常处理。

ErrorReportValve

用于在界面上展示错误信息,也就是常见的错误提示:

StandardWrapperValve

收集执行Servlet过程中的错误信息,给ErrorReportValve进行展示。

3,springmvc 异常定制以及扩展

请求处理流程
使用@ControllerAdvice & @ExceptionHandler 配置全局异常处理器

用于处理 HandlerMethod(上图中 Handler) 执行过程中抛出的异常

未配置全局异常处理或者没有匹配到异常时的处理流程
  1. springboot在启动时,自动配置机制,使用 ErrorMvcAutoConfiguration 中注册:BasicErrorController

  2. 同时,注册code为0的ErrorPage
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration.ErrorPageCustomizer#registerErrorPages

    复制代码
     	@Override
     	public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
     		ErrorPage errorPage = new ErrorPage(
     				this.dispatcherServletPath.getRelativePath(this.properties.getError().getPath()));
     		errorPageRegistry.addErrorPages(errorPage);
     	}

by the way:code为0的错误页面映射,tomcat中的处理逻辑如下:

复制代码
//org.apache.catalina.valves.ErrorReportValve

    protected void report(Request request, Response response, Throwable throwable) {

        int statusCode = response.getStatus();

        // Do nothing on a 1xx, 2xx and 3xx status
        // Do nothing if anything has been written already
        // Do nothing if the response hasn't been explicitly marked as in error
        //    and that error has not been reported.
        if (statusCode < 400 || response.getContentWritten() > 0 || !response.setErrorReported()) {
            return;
        }

        // If an error has occurred that prevents further I/O, don't waste time
        // producing an error report that will never be read
        AtomicBoolean result = new AtomicBoolean(false);
        response.getCoyoteResponse().action(ActionCode.IS_IO_ALLOWED, result);
        if (!result.get()) {
            return;
        }

        ErrorPage errorPage = null;
        if (throwable != null) {
            errorPage = errorPageSupport.find(throwable);
        }
        if (errorPage == null) {
            errorPage = errorPageSupport.find(statusCode);
        }
        if (errorPage == null) {
            // Default error page
            errorPage = errorPageSupport.find(0);
        }
	... //忽略部分代码
	}
  1. 经过code为0的映射处理后,tomcat container组件会把请求dispatch到"/error"页面,最终找到BasicErrorController 处理器:
    BasicErrorController 处理器的处理逻辑如下:
    BasicErrorController 通过 Accept 头判断需要生成哪种 MediaType 的响应
    3.1 如果要的不是 text/html,走 MessageConverter 流程
    3.2 如果需要 text/html,走 mvc 流程,此时又分两种情况
    a. 配置了 ErrorViewResolver,根据状态码去找 View
    b. 没配置或没找到,用 BeanNameViewResolver 根据一个固定为 error 的名字找到 View,即所谓的 WhitelabelErrorView
以上处理过程中的未捕获异常,交给tomcat去处理异常

返回给tomcat的ErrorReportValve去处理,展示异常如前图所示。

相关推荐
S***267520 分钟前
基于SpringBoot和Leaflet的行政区划地图掩膜效果实战
java·spring boot·后端
马剑威(威哥爱编程)39 分钟前
鸿蒙6开发视频播放器的屏幕方向适配问题
java·音视频·harmonyos
JIngJaneIL43 分钟前
社区互助|社区交易|基于springboot+vue的社区互助交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·社区互助
V***u4531 小时前
MS SQL Server partition by 函数实战二 编排考场人员
java·服务器·开发语言
这是程序猿1 小时前
基于java的ssm框架旅游在线平台
java·开发语言·spring boot·spring·旅游·旅游在线平台
i***t9192 小时前
基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
java·spring boot·spring
k***08292 小时前
【监控】spring actuator源码速读
java·spring boot·spring
麦麦鸡腿堡2 小时前
Java_网络编程_InetAddress类与Socket类
java·服务器·网络
一 乐2 小时前
应急知识学习|基于springboot+vue的应急知识学习系统(源码+数据库+文档)
数据库·vue.js·spring boot
@大迁世界2 小时前
相信我兄弟:Cloudflare Rust 的 .unwrap() 方法在 330 多个数据中心引发了恐慌
开发语言·后端·rust