前言在平时的 api 开发过程中,总会遇到一些错误异常没有捕捉到的情况。那有的小伙伴可能会想,这还不简单么,我在 api 最外层加一个 try...catch 不就完事了。
哈哈哈,没错。这种方法简单粗暴。小编曾经也是这么干的,但是你转过来想一想,你会在每一个 api 入口,都去做 try...catch 吗?这样不是代码非常丑陋的。小伙伴开始思考,突然灵光一现,说我们实现一个 aop 来做这事不就完了。没错,使用 aop 来实现是最佳的选择。
现在就给大家来介绍介绍 spring boot 怎么通过注解来实现全局异常处理的。
主角 @controlleradvice 和 @exceptionhandler我们先来介绍一下今天的主角,分别是 @controlleradvice 和 @exceptionhandler 。
@controlleradvice 相当于 controller 的切面,主要用于 @exceptionhandler, @initbinder 和 @modelattribute,使注解标注的方法对每一个 controller 都起作用。默认对所有 controller 都起作用,当然也可以通过 @controlleradvice 注解中的一些属性选定符合条件的 controller 。@exceptionhandler 用于异常处理的注解,可以通过 value 指定处理哪种类型的异常还可以与 @responsestatus 搭配使用,处理特定的 http 错误。标记的方法入参与返回值都有很大的灵活性,具体可以看注释也可以在后边的深度探究。案例分析今天我们就通过几种案例的方式,来给大家分析分析,怎么通过全局异常处理的方式玩转 spring boot 的全局异常处理。
案例一一般的异常处理,所有的api都需要有相同的异常结构。
exception1
在这种情况下,实现是非常简单的,我们只需要创建 generalexceptionhandler 类,用 @controlleradvice 注解来注解它,并创建所需的 @exceptionhandler ,它将处理所有由应用程序抛出的异常,如果它能找到匹配的 @exceptionhandler,它将相应地进行转换。
@controlleradvicepublic class generalexceptionhandler { @exceptionhandler(exception.class) protected responseentity handleexception(exception ex) { myerror myerror = myerror.builder() .text(ex.getmessage()) .code(ex.geterrorcode()).build(); return new responseentity(myerror, httpstatus.valueof(ex.geterrorcode())); }}案例二我们有一个api,它需要有一个或多个异常以其他格式处理,与其他应用程序的 api 不同。
exception2
我们可以采取两种方式来实现这种情况。我们可以在 othercontroller 内部添加 @exceptionhandler 来处理 otherexception ,或者为 othercontroller 创建新的@controlleradvice,以备我们也想在其他 api 中处理 otherexception。
在 othercontroller 中添加 @exceptionhandler 来处理 otherexception 的代码示例。
@restcontroller@requestmapping(/other)public class othercontroller { @exceptionhandler(otherexception.class) protected responseentity handleexception(otherexception ex) { myothererror myothererror = myothererror.builder() .message(ex.getmessage()) .origin(other api) .code(ex.geterrorcode()).build(); return new responseentity(myothererror, httpstatus.valueof(ex.geterrorcode())); }}只针对 othercontroller 控制器的 @controlleradvice 的代码示例
@controlleradvice(assignabletypes = othercontroller.class)public class otherexceptionhandler { @exceptionhandler(otherexception.class) protected responseentity handleexception(otherexception ex) { myothererror myothererror = myothererror.builder() .message(ex.getmessage()) .origin(other api) .code(ex.geterrorcode()).build(); return new responseentity(myothererror, httpstatus.valueof(ex.geterrorcode())); }}案例三与案例二类似,我们有一个 api 需要以不同于应用程序中其他 api 的方式对异常进行格式化,但这次所有的异常都需要进行不同的转换。
exception3
为了实现这个案例,我们将不得不使用两个 @controlleradvice,并加上 @order 注解的注意事项。因为现在我们需要告诉 spring,在处理同一个异常时,哪个 @controlleradvice 的优先级更高。如果我们没有指定 @order,在启动时,其中一个处理程序将自动注册为更高的顺序,我们的异常处理将变得不可预测。例如,我最近看到一个案例,如果你使用 mvn springboot:run 任务启动一个应用程序,otherexceptionhandler 是主要的,但是当以jar形式启动时,generalexceptionhandler 是主要的。
@controlleradvicepublic class generalexceptionhandler { @exceptionhandler(exception.class) protected responseentity handleexception(exception ex) { myerror myerror = myerror.builder() .text(ex.getmessage()) .code(ex.geterrorcode()).build(); return new responseentity(myerror, httpstatus.valueof(ex.geterrorcode())); }}@controlleradvice(assignabletypes = othercontroller.class)@order(ordered.highest_precedence)public class otherexceptionhandler { @exceptionhandler(exception.class) protected responseentity handleexception(exception ex) { myerror myerror = myerror.builder() .message(ex.getmessage()) .origin(other api) .code(ex.geterrorcode()).build(); return new responseentity(myerror, httpstatus.valueof(ex.geterrorcode())); }}总结经过上述的几个案例,指北君觉得大家应该已经能够轻松应对 spring boot 中大部分的全局异常处理的情况。
细心的同学也许会觉得为什么不使用 @restcontrolleradvice 呢?如果是用的 @restcontrolleradvice 注解,它会将数据自动转换成json格式,不再需要 responseentity 的处理来。这种与 controller 和 restcontroller 类似,本质是一样的,所以我们在使用全局异常处理之后可以进行灵活的选择处理。
橡胶输送带划伤的修复方法及注意事项
Altera和嵌入式联盟合作伙伴提供的处理器
Python面试中一些常见的问题及其答案
一加5什么时候上市?最新消息:一加5旗舰即将发布,真机被吐槽神似oppor11、iphone7 plus,刘作虎暗示摸完再说话!
浅析战场中的“互联网”
Spring Boot怎么通过注解来实现全局异常处理的
海信今年将成为业内首家推出XDR电视的厂商
不锈钢刀型闸阀安装时的常见问题都有哪些
NI无线通信USRP X410 LabVIEW套件赋能四大发展路径
新能源pack电池包气密性测试方法是怎样的
高通喊话苹果:禁止在中国生产和销售iPhone
美商务部批准约1/4特定厂商恢复与华为贸易
Strategy Analytics:2013年带插槽手机出
鲁大师发布了8月新发布的手机性能排行榜努比亚Z20以450040分居第一
还记得2018年Wider Challenge吗?现在结果出来啦
商业BI大数据分析系统开发可视化大屏BI大数据分析系统
电源电路中钽电容的应用选型
PLC的通讯介质和协议内容介绍
高工LED照明出口月度景气指数
什么是chirpiot,与现有lora技术的区别