1|0springboot之全局处理异常封装
1|1简介
在项目中经常出现系统异常的情况,比如NullPointerException
等等。如果默认未处理的情况下,springboot
会响应默认的错误提示,这样对用户体验不是友好,系统层面的错误,用户不能感知到,即使为500
的错误,可以给用户提示一个类似服务器开小差
的友好提示等。
在微服务里,每个服务中都会有异常情况,几乎所有服务的默认异常处理配置一致,导致很多重复编码,我们将这些重复默认异常处理可以抽出一个公共starter
包,各个服务依赖即可,定制化异常处理在各个模块里开发。
1|2配置
unified-dispose-springboot-starter
这个模块里包含异常处理以及全局返回封装等功能,下面。
完整目录结构如下:
异常处理
@RestControllerAdvice
或者 @ControllerAdvice
为spring
的异常处理注解。
我们先创建GlobalDefaultExceptionHandler
全局异常处理类:
大致内容处理了一些项目常见的异常Exception
,BindException
参数异常等。
这里将默认的404
、405
、415
等默认http
状态码也重写了。
重写这个默认的状态码需要配置throw-exception-if-no-handler-found
以及add-mappings
。
ps: 请注意这两个配置会将静态资源忽略。
请产考WebMvcAutoConfiguration#addResourceHandlers
Exception
为了防止未知的异常没有防护到,默认给用户返回服务器开小差,请稍后再试
等提示。
具体异常默认会以小到大去匹配。
如果抛出BindException
,自定义有BindException
就会去这个处理器里处理。没有就会走到它的父类去匹配,请参考java-异常体系
。
其他已知异常可以自己用@ExceptionHandler
注解进行捕获处理。
通用异常枚举
为了避免异常值不好维护,我们使用CommonErrorCode
枚举把常见的异常提示维护起来。
其实starter
包中不建议使用@Getter
等lombok
注解,防止他人未使用lombok
依赖该项目出现问题。
通用业务异常
这两个类完成基本可以正常使用异常拦截了,不过为了业务方便,我们创建一个一般通用的业务异常。
BusinessException
继承RuntimeException
即可。
将BusinessException
加入GlobalDefaultExceptionHandler
全局异常拦截。
程序主动抛出异常可以通过下面方式:
通常不建议直接抛出通用的BusinessException异常,应当在对应的模块里添加对应的领域的异常处理类以及对应的枚举错误类型。
如会员模块:
创建UserException
异常类、UserErrorCode
枚举、以及UserExceptionHandler
统一拦截类。
UserException:
UserErrorCode:
UserExceptionHandler:
最后业务使用如下:
加入spring容器
最后将GlobalDefaultExceptionHandler
以bean
的方式注入spring
容器。
将GlobalDefaultConfiguration
在resources/META-INF/spring.factories
文件下加载。
不过我们这次使用注解方式开启。其他项目依赖包后,需要添加@EnableGlobalDispose
才可以将全局拦截的特性开启。
将刚刚创建的spring.factories
注释掉,创建EnableGlobalDispose
注解。
使用@Import
将GlobalDefaultConfiguration
导入即可。
使用
添加依赖
启动类开启@EnableGlobalDispose
注解即可。
1|3总结
项目里很多重复的code,我们可以通过一定的方式去简化,以达到一定目的减少开发量。
示例代码地址:unified-dispose-springboot
作者GitHub:
Purgeyao 欢迎关注