• 【springboot异常处理】


    1,Java Servlet规范

    异常处理

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

    
     
        404          
        /404.html
    
    
    
     
        0          
        /error.html
    
    
    
     
        java.lang.NullPointerException          
        /error.html
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    触发异常

    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);
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    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去处理,展示异常如前图所示。

  • 相关阅读:
    Linux系统防火墙限制ssh连接
    MT1283·区间Disarium数
    redis-migrate-tool数据迁移工具测试
    社区志愿者招募管理系统
    Linux中的tar
    Hubble数据库再获得国家级重点项目推荐,作为HTAP国产数据库入选工信部全国试点
    Linux|shell编程|拷贝大文件之显示进度条
    Gateway服务网关
    『Java 语法基础』面向对象有哪些特性
    spring boot 2.7 -> 3.0升级指南
  • 原文地址:https://blog.csdn.net/weixin_43493520/article/details/133935344