springboot异常处理

本文围绕Spring Boot的异常处理展开,先回顾Spring MVC的异常处理方式,接着介绍Spring Boot中处理异常的多种方法,如实现ErrorController、自定义HandlerExceptionResolver等。还分析了异常处理的原理,包括通过BasicErrorController和HandlerExceptionResolver处理异常,最后给出参考链接和代码仓库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于异常的处理可以说是一个系统完整与文档的关键,它能够帮助我们对行为故障做出对于的反馈,对业务逻辑进行合理的补偿,但是如何处理异常,对系统中格式各样的异常如何制定对应的处理模式。

说到springboot的异常处理,可以先回忆下在springmvc中是如何处理的

1、@ExceptionHandler 通过在Controller中指定的方法上针对请求时出现的异常做下一步处理

2、HandlerExceptionResolver 通过向spring容器中注入实现bean,出现异常时自动调用对应的处理方法

在springboot中,处理异常的主要原理还是一样,不同点在于框架引入了一些默认的实现方法,在没有进行任何配置的时候,有默认方案保证系统整个流程的完整性。首先可以看下在springboot中如何处理异常。

1、通过实现接口 ErrorController或者继承其子类AbstractErrorController、BasicErrorController,然后注册到容器中,其主要目的是获取请求异常后重定向到指定的错误请求路径,默认请求为 /error

说明:该异常处理方式针对的是servlet底层,比如我们输入一个不存在的请求路径,这样不会经过spring的handle,最终反馈个servlet。不需要额外的配置,异常处理的转发请求可以通过server.error.path重新定义(默认/error),通过ErrorViewResolver定义返回的ModelAndView,目前是error。当然在BasicErrorController支持页面域json两种返回模式。如果需要特定的样式的页面需要加入对应的试图解析器,现在使用的是BeanNameViewResolver,同时如果默认的json格式不符合也需要自定义。

2、自定义HandlerExceptionResolver,并通过WebMvcConfigurerAdapter配置到应用中去,这里有必要说明的是,在其重写方法中提供了两个:

  • configureHandlerExceptionResolvers:如果我们通过该方法将自定义的异常处理器注册进去,那么系统默认的则会被放弃
    
  • extendHandlerExceptionResolvers:而通过该方法注册,则想当与系统默认配置处理完成后在进行扩展,那么自定义的与系统的异常处理全部都能正常使用

说明:既然是自定义,那么就非常灵活了,可以根据自己的需要随意处理。当然因为HandlerExceptionResolver的返回类型是ModelAndView,因此返回的是视图,当然你可以重写它啊,也可以让它返回json。

3、通过@ControllerAdvice与@ExceptionHandler搭配,但是要注意,该实现依赖于ExceptionHandlerExceptionResolver,而该处理器属于系统默认提供的,如果在方法2中将其忽略,需要添加进去

说明:使用简单,对代码没有任何注入的情况下,完成异常处理,如果说可以按异常类型细化处理,当然方法2也行;

4、通过往容器中注入bean EmbeddedServletContainerCustomizer来实现自定义异常页面

说明:和方法1类似,主要原理是对Servlet层级的异常进行处理,可以根据请求状态将异常分发到不同请求上。

可以看到,各种方法都可以完全实现对异常的处理,如果是spring容器内的异常,我们可以使用2、3方式处理;如果是servlet层面的,则通过1、4。

总的来说,springboot针对异常的处理主要都是通过HandlerExceptionResolver来实现的,如果有多个时,注意是按照顺序来执行的,当然我们一般不会配置那么多相似的HandlerExceptionResolver,但是如果不是按正常逻辑走时,可以关注下是否因为这原因。

原理分析:

1、通过BasicErrorController处理异常

在使用springboot时,如果后台出现异常,我们经常会看到这样的画面

那到底是怎样的逻辑导致这样,我们首先从springboot自动化的配置说起,spring-boot-autoconfigure/META-INF/spring.factories,

与mvc相关的自动配置

org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration

org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration

重点是在ErrorMvcAutoConfiguration中,看代码

其使用则是在ErrorPageRegistrarBeanPostProcessor

而对其的注册则是在前面说到的spring.factories中EmbeddedServletContainerAutoConfiguration完成。其实看具体代码,关键点是

ErrorPage errorPage = new ErrorPage(this.properties.getServletPrefix()
      + this.properties.getError().getPath());
errorPageRegistry.addErrorPages(errorPage);

errorPageRegistry是个什么?看到其实现类有

我们知道,springboot内置了tomcat容器,那十有八九就是TomcatEmbeddedServletContainerFactory,具体为什么,去spring.factories中找,应该有容器相关的自动配置,里面会有当前具体是哪个容器。那么到这里继续往下看,

剩下的就是当tomcat容器接收到请求后如何请求的过程了,这里就不做更深入的探讨,但是可以看到一个问题,我们一般通过jar启动springboot项目使用了内置tomcat,但是如果我们将项目打包成war,放在自己的tomcat中,那么还有有这一系列的处理吗?答案是否定的。

再看看方法4,其实是如出一辙的方式,同样是将请求错误状态对应的请求路径注册到tomcat容器中了。

2 通过HandlerExceptionResolver处理异常

2、3方法都是通过HandlerExceptionResolver来处理异常的,具体怎么做可以看下比较熟悉的DispatcherServlet,每次请求过来都会调用Servlet的doService -> doDispatch -> processDispatchResult -> processHandlerException 就可以看到

这个会根据我们配置的HandlerExceptionResolver顺序来操作,而且一段返回值不为null则终止。

这里特别要说下的是@ControllerAdvice,如果我们配置了两个,那么会先执行哪一个?这个还是得看HandlerExceptionResolver的顺序了。

总结:

1、默认情况下springboot异常处理在ErrorMvcAutoConfiguration配置,主要是通过其内置的tomcat完成,针对内部异常,将错误指向/error->BasicErrorController进行处理,
但是要注意,同时通过BeanNameViewer这个视图解析器来完成error最终的显示。要注意的是,这个处理内部异常;基于内置tomcat异常。
2、通过继承AbstractErrorController可以覆盖BasicErrorController,改写其默认逻辑
3、通过重写ErrorAttributes可以在BasicErrorController的处理逻辑上修改返回值
4、通过实现HandlerExceptionResolver可以覆盖或扩展默认的异常处理器,这个使用时要注意
5、通过@ControllerAdvice可以实现Controller的异常统一处理
6、通过注册EmbeddedServletContainerCustomizer可以根据不同响应错误定位不同处理页面比如404、500...,同1类似

参考:https://www.cnblogs.com/FlyAway2013/p/7944568.html

代码:https://github.com/suspring/springboot-exception.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值