当前位置:网站首页>统一异常处理导致ResponseBodyAdvice失效
统一异常处理导致ResponseBodyAdvice失效
2022-07-30 08:16:00 【AE86Jag】
背景
微服务架构下准备将一些基础功能抽出到公共Jar包中,包括统一异常处理、JwtToken校验、统一请求响应处理等,抽完以后发现,当出现异常时,走了统一异常捕获的逻辑,但是项目中的所有自定义的ResponseBodyAdvice都没有执行,决定一步步DEBUG定位下原因,项目是Springboot 2.3.7.RELEASE版本。
定位过程
首先测试正常的接口,发现ResponseBodyAdvice都是生效的,而且按照设置的顺序执行了,说明这些ResponseBodyAdvice都注册到容器了。
接着猜测是不是ResponseBodyAdvice都执行过只是没有执行beforeBodyWrite方法,在执行supports方法的时候就已经返回,于是在supports方法里面打上断点,看抛异常时是否会走到supports方法,最后发现都没有走supports方法,猜测可能是因为什么规则,把ResponseBodyAdvice都过滤了。
继续DEBUG,看正常流程下ResponseBodyAdvice是如何生效的,因为之前在supports方法都打了断点,直接请求接口,看supports方法之前的调用调用堆栈,如图
主要是前面几个类,栈顶是我自定义的ResponseBodyAdvice,断点打在supports方法上,下面是RequestResponseBodyAdviceChain的processBody方法140行,然后是RequestResponseBodyAdviceChain的beforeBodyWrite方法116行,AbstractMessageConverterMethodProcessor类的writeWithMessageConverters268行,分别在这几个方法上打断点:
下面会走RequestResponseBodyAdviceChain的beforeBodyWrite方法,继续进去看下
for循环里面就是实际去调用每个advice去处理返回结果,要过滤就只能在getMatchingAdvice方法里面了,继续DEBUG
getAdvice()就是获取系统中所有的Advice,因为自定义的ResponseBodyAdvice都是有@ControllerAdvice注解修饰的,所以都是ControllerAdviceBean类型,走的157行的逻辑。parameter参数就是最终返回数据的方法参数,我这里就是统一异常处理的方法。继续进入
可以看到这个方法调用了beanTypePredicate的test方法,beanTypePredicate里面有三个属性,其中有一个是basePackages,在自定义的ResponseBodyAdvice中@RestControllerAdvice指定了包名,其他两个assignableTypes、annotations也是该注解的属性。继续看test方法的内容
到这就能大概知道原因了,就是包名不匹配,ResponseBodyAdvice只能处理指定包名下的返回值处理。其他两个属性可以实现指定注解或者Class类实现ResponseBodyAdvice的功能:
- annotations属性,如果返回的方法不在basePackages包内,直接在方法上指定这个注解
- assignableTypes属性,如果不在basePackages包内,也没有annotations注解,指定Class类也可以
原因
统一异常处理类所在的包名不在@RestControllerAdvice注解的basePackages属性指定的包名下,所以自定义的ResponseBodyAdvice是处理不了统一异常处理返回的数据的
解决方法
- 修改包名,basePackages的包名包含统一异常处理的类
- 增加自定义注解,修饰在异常处理的方法上,并把这个注解写在@RestControllerAdvice注解的annotations属性上
- 将异常处理的类Class对象写在@RestControllerAdvice注解的assignableTypes属性上
总结
框架异常多看源码,多调试,有很大收获。
边栏推荐
- How to run dist file on local computer
- Reflection tricks can boost your performance by N times
- 集合相关Collection
- typescript1 - what is typescript
- 看完这100个客户需求,我终于知道企业文档管理的秘密
- 2022 Hangzhou Electric Multi-School 1st Game
- ClickHouse
- 电源完整性的去耦和层间耦合电容
- typescript8 - type annotations
- [Mini Program Column] Summarize the development specifications of uniapp to develop small programs
猜你喜欢
随机推荐
与tcp协议有关的几个知识点
蓝牙技术|了解蓝牙LE Audio的Auracast广播音频
瑞吉外卖项目(五) 菜品管理业务开发
七大排序之直接选择排序
【无标题】
如何组装一个注册中心
新手必备!最全电路基础知识讲解
What convenience does the RFID fixed asset inventory system bring to enterprises?
[Unity]UI切换环形滚动效果
ACL 2022 | 引入角度margin构建对比学习目标,增强文本语义判别能力
Splunk tag 的利用场景
Circuit analysis: constant current source circuit composed of op amp and triode
Integral Special Notes - Definition of Integral
Is R&D moving to FAE (Field Application Engineer), is it moving away from technology?Is there a future?
经典毕业设计:基于SSM实现高校后勤报修系统
内卷下的智能投影行业,未来何去何从?
opencv可以有多有趣
ES报错处理-mapper [xx.xx] of different type, current_type [text], merged_type [keyword]
【网络攻防】常见的网络攻防技术——黑客攻防(通俗易懂版)
【WeChat Mini Program】Page Events