网站制作视频教程,网站公司怎么做的,海南在线海南一家,最新手机排行前言我们在开发应用系统时#xff0c;不可避免的要使用到我们自己定义的异常#xff0c;所以我们一般通常会用到自定义的业务异常类BusinessException#xff0c;这个异常会继承extends RuntimeException#xff0c;当发生业务限制的时候#xff0c;会throw出来。问题在Sp…前言我们在开发应用系统时不可避免的要使用到我们自己定义的异常所以我们一般通常会用到自定义的业务异常类BusinessException这个异常会继承extends RuntimeException当发生业务限制的时候会throw出来。问题在SpringMVC项目中我们可以采用ControllerAdvice注解拦截我们的业务异常类然后做一些处理。网上有很多SpringMVC项目如何统一处理异常。老顾这里就不做介绍但是现在项目都是微服务化的在使用dubbo构建项目时会发现provider抛出自定义业务异常在custom端并不能正确的捕获。即便我们在provider和custom都有导入相同jar包下面的BusinessException异常并且抛出这个异常。下面是出错情况老顾采用dubbo版本为2.7.3版本跟老版本有点区别但区别不大provicer生产者代码其中的DataNotFoundException继承了BusinessExceptionDataNotFoundException 的编码以及错误信息 PUBLIC_DATA_NOT_FOUND(1001,数据没有找到) consumer消费者代码运行输入不存在的goodsID我们期望我们自定义的异常类被我们拦截到并做一些处理但是provider生产端抛给消费者的异常竟然是RuntimeException只是里面的message是我们的业务异常调用栈信息。如下不是我们希望的抛给消费者端是DataNotFoundException异常。导致我们消费端没法针对不同的业务进行不同的处理。消费端做了SpringMVC的异常处理返回了上面的code为1401是系统异常编码并不是DataNotFoundException编码。我们定义的DataNotFoundException的编码为1001为什么产生我们来看看dubbo的源码进行分析如果Dubbo的 provider端 抛出异常(Throwable)则会被 provider端 的ExceptionFilter拦截到执行以下invoke方法里面有个实现Listener类重写了onResponse。我们来分析一些代码if (appResponse.hasException() GenericService.class ! invoker.getInterface())上面代码的含义就是 如果有异常并且未实现GenericService接口进入后续判断逻辑否则直接返回结果。上面代码的含义就是 不是RuntimeException类型的异常并且是受检异常(继承Exception)直接抛出。上面代码的含义就是 在方法签名上有声明直接抛出。上面代码的含义就是 如果异常类和接口类在同一个jar包中直接抛出。上面代码的含义就是 以java.或javax.开头的异常直接抛出。上面代码的含义就是dubbo自身的异常直接抛出。不满足上述条件会做toString处理并被封装成RuntimeException抛出。现在我们知道了 为什么我们自定义的异常没有正确的抛出这个是因为上面的几个条件我们都没有满足所以最后dubbo把它封装成了RuntimeException。如何解决解决方法就针对上面的几个条件进行有几种方案我们一一看一下1、将该异常的包名以java.或者javax.开头这个方案不现实也不符合规范所以不采用2、业务异常继承Exception变为checked异常自定义的业务异常本身属于RuntimeException所以也不采用3、异常类和接口类在同一jar包里较大的项目一般都会有一些common包定义好异常类型使用二方包的方式引用所以也不适用4、provider的api明确写明throws XxxException作为生产服务端不应显式抛出异常给客户的进行处理所以也不适用最终方案以上方案都不合适我们这里介绍个最终的方案即采用dubbo的filter重写dubbo的异常处理。1、将dubbo源码中ExceptionFilter复制到我们的项目改名为DubboExceptionFilter修改一些代码2、在此处加上一段代码来过滤我们项目中的异常以免被dubbo重新封装3、在resources目录下添加纯文本文件META-INF/dubbo/com.alibaba.dubbo.rpc.Filter并添加内容dubboExceptionFiltercom.rainbow.goods.server.filter.DubboExceptionFilter4、修改dubbo 的配置文件将DubboExceptionFilter加载进去并且去掉自身的ExceptionFilter上面exception就是dubbo默认的处理异常的filter前面-号就代表去除我们修改后再运行抛出的是我们自定义的异常了在看看消费端的异常处理最终显示确实是我们定义的DataNotFoundException业务异常的编码和信息。总结上面的是基于重写dubbo的filter处理了异常网上有一些别的方案老顾认为不是太合理不够灵活利用修改dubbo源码的方式解决更能彻底解决希望能够给小伙伴带来帮助。谢谢