Java开发从工作到原理--BasicErrorController统一异常处理

依照Java开发从工作到原理--Spring Boot单体项目运行日志解析中提到的常见配置项修改后的配置信息如图:

IDEA社区版对properties文件不支持配置项提示功能,因此这里换成是yml文件

重新启动日志信息变为:

各项配置修改都已经生效

之前在DemoApplication类中,我们通过增加了一个方法实现了一个可访问的http API接口

代码未做任何修改

访问需加上content path配置前缀

这里是在DemoApplication类里面写的接口,正常情况是创建一个controller包用于专门存放controller类。

最简单的controller

直接运行,然后进行接口访问为如下结果:

 

报错返回404

错误提示中”This application has no explicit mapping for /error, so you are seeing this as a fallback.“,意思是说程序没有配置直接的错误页面,所以返回了这样一个统一的错误页面。

所以我们可以定义一个统一的错误页面。

SpringMVC是通过BasicErrorController进行统一的异常处理的,在IDEA中点两次SHIFT键可以唤起搜索框,输入BasicErrorController可以找到对应的.class文件,如果maven下载了源代码还可看到BasicErrorController.java源文件如下图:

唤起的搜索框中选择files tab

选择java文件可以直接查看源代码,选择class文件会看到idea反编译出来的代码,会提示是否下载源代码。

以看到@RequestMapping中的配置是支持EL表达式读取配置信息的

最主要的两个方法:

第一个方法向客户端返回html格式的错误信息,第二个方法向客户端返回json格式错误信息

给这两个方法都加上断点,以debug模式启动程序进行调试,查看SpringMVC的处理机制。

在浏览器访问http://localhost:8080/api/test/test地址后,

进入到errorHtml方法中

线程堆栈情况为:

DispatcherServlet之前的调用链为tomcat的调用链

到DispatcherServlet.onDispatch方法中查看的信息是

根据请求信息从handlerMappings中获取到的HandlerMethod就是BasicErrorController的errorHtml方法

进入getHandler方法打断点重新进行调试

设置条件断点,根据请求地址判断

此时handlerMappings中有7个对象

当执行到RequestMappingHandlerMapping获得了HandlerMethod为TestController.test方法

此次getHandler方法调用返回与最终的handlerMethod并不相同

而TestController.test的返回值为”thank you!“,SpringMvc将其作为要访问view的一个相对路径进行解析,与当前请求地址同一级别,获得view的真实访问路径为”/test/thank you!“,加上contextPath后完整路径为”/api/test/thank you!“,然后进行forward,因此DispatcherServlet接收到第二个请求如图:

如果TestController.test的返回值改为”/thank you!“,则SpringMVC解析的转发地址为"/thank you!",加上contextPath后完整路径为”/api/thank you!“,然后进行forward,因此DispatcherServlet接收到第二个请求如图:

而很显然这两个地址都没有对应controller和处理方法的,所以获得的mappedHandler是用来处理静态资源的ResourceHttpRequestHandler,很显然静态资源中依然没有对应的页面,所以会返回404状态码。而tomcat会根据状态码显示一个特定的页面,没有SpringBoot之前特定页面的配置是在web.xml中配置的

<error-page>
	<error-code>404</error-code>
	<location>/error/notFoundError.jsp</location>
</error-page>

这就涉及到Spring Boot中对于j2ee底层的一些操作,比如在SpringBoot中进行自定义Servlet,Filter,Listener,而这里配置的是ErrorPage。

还是在IDEA中点两次SHIFT键可以唤起搜索框,选择Files tab,输入ErrorPage,很幸运有很多结果:

选择在org.springframework包下的ErrorPage类

只是一个简单的类,没有任何注解

对三个构造函数进行Callers查询,得出的结果只有ErrorMvcAutoConfiguration类中的ErrorPageCustomizer内部静态类调用过。

方法中进行ErrorPage对象的创建并添加到ErrorPageRegistry对象中

对registerErrorPages方法进行Callers查询,得出结果只有ErrorPageRegistrarBeanPostProcessor.postProcessBeforeInitialization(ErrorPageRegistry registry)方法中调用过。这样SpringBoot默认有的ErrorPage的来处就找出来了:ErrorPageRegistrarBeanPostProcessor找出所有托管给Spring的ErrorPageRegistrar,由ErrorPageRegistrar将ErrorPage注册到ErrorPageRegistry中。

ErrorPageRegistry是一个接口,查看ErrorPageRegistry的实现类有

要跟http容器对接,所以tomcat,jetty,undertow对应的都有

目前项目使用tomcat,且并非reactive,所以使用的应该是TomcatServletWebServerFactory,而TomcatServletWebServerFactory.configureContext方法会将所有ErrorPage(springboot中的类)转换成tomcat中的ErrorPage对象,并添加到TomcatEmbeddedContext中。TomcatServletWebServerFactory.configureContext会在ApplicationContext.refresh方法中启动Web容器时调用。

回到ErrorPageCustomizer中ErrorPage的构造参数path的值为server.error.path的配置值,而这个值又是BasicErrorController类上配置的访问地址,因此当出现404异常时,由tomcat的error-page机制访问到BasicErrorController中的方法。

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
【2021年,将Spring全家桶的课程进行Review,确保不再有课程的顺序错乱,从而导致学员看不懂。进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并开始加入高阶Spring Security等内容,一步步手把手教你从零开始学会应用Spring,课件将逐步进行上传,敬请期待!】 本课程是Spring全家桶系列课程的第三部分Spring Boot,Spring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Spring Boot核心知识点:整合Web(如:JSP、Thymeleaf、freemarker等的整合)的开发、全局异常处理、配置文件的配置访问、多环境的配置文件设置、日志Logback及slf4j的使用、国际化设置及使用, 并在最后以一个贯穿前后台的Spring Boot整合Mybatis的案例为终奖,使大家快速掌握Spring的核心知识,快速上手,为面试、工作都做好充足的准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring的原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。 【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring Boot、Spring Cloud及Spring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验  【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值