老顾导读
1、背景
2、为什么自定义异常
3、如何自定义异常
4、测试
5、总结
一、前言
我们平时在用SpringMVC的时候,只要是经过DispatcherServlet处理的请求,可以通过@ControllerAdvice和@ExceptionHandler自定义不同类型异常的处理逻辑。
具体可以参考老顾以前的文章,有过介绍
SpringMVC中提供的自定义异常体系在Spring-WebFlux中并不适用,其实原因很简单,两者底层的运行容器并不相同。WebExceptionHandler是Spring-WebFlux的异常处理器顶层接口,因此追溯到子类可以追踪到DefaultErrorWebExceptionHandler是Spring Cloud Gateway的全局异常处理器,配置类是ErrorWebFluxAutoConfiguratio。
二、为什么要自定义异常处理
我们看一下上图,网关在整个架构中的作用是
1、路由服务端应用的请求到后端应用
2、(聚合)后端应用的响应转发到服务端应用
假设网关服务总是正常的前提下:
对于第1点来说,假设后端应用不能平滑无损上线,会有一定的几率出现网关路由请求到一些后端的“僵尸节点(请求路由过去的时候,应用更好在重启或者刚好停止)”,这个时候会路由会失败抛出异常,一般情况是Connection Refuse
对于第2点来说,假设后端应用没有正确处理异常,那么应该会把异常信息经过网关转发回到服务端应用,这种情况理论上不会出现异常。
其实还有第3点隐藏的问题,网关如果不单单承担路由的功能,还包含了鉴权、限流等功能,如果这些功能开发的时候对异常捕获没有做完善的处理甚至是逻辑本身存在BUG,有可能导致异常没有被正常捕获处理,走了默认的异常处理器DefaultErrorWebExceptionHandler,默认的异常处理器的处理逻辑可能并不符合我们预期的结果。
三、如何自定义异常处理
我们可以先看默认的异常处理器的配置类ErrorWebFluxAutoConfiguration:
注意到两个Bean实例ErrorWebExceptionHandler和DefaultErrorAttributes都使用了@ConditionalOnMissingBean注解,也就是我们可以通过自定义实现去覆盖它们。先自定义一个CustomErrorWebFluxAutoConfiguration
(除了ErrorWebExceptionHandler的自定义实现,其他直接拷贝ErrorWebFluxAutoConfiguration):
errorWebExceptionHandler方法中替换自定义的ErrorWebExceptionHandler
自定义的JsonErrorWebExceptionHandler如下:
上面的代码中,三个注意点
1、getErrorAttributes用来自定义返回参数,当然小伙伴可以根据自身业务,更细致的区分返回参数。
2、getHttpStatus返回Http的状态码,也可以结合业务区分不同的状态码
3、异常时如何返回JSON而不是HTML?
getRoutingFunction方法,默认优先以Html格式返回
改为JSON格式,如下:
四、测试
测试场景一:只启动网关,下游服务不启动的情况下直接调用下游服务:
测试场景二:下游服务正常启动和调用,网关自身抛出异常。 过滤器中加入代码int a=1/0会产生异常。
五、总结
网关的异常处理是非常重要的,任何一个项目都需要自行定义本业务相关的异常,小伙伴可以关注自己公司的业务,是不是都有自定义异常?今天老顾就分享到这里。
领取专属 10元无门槛券
私享最新 技术干货