项目场景:
dubbo服务提供端抛出自定义异常BusinessException,消费端捕获后统一封装处理数据。
问题描述:
消费端捕获的异常类却为RuntimeException,根据打印异常信息,发现dubbo服务端自定义异常被封装成RuntimeException后抛出,如下所示:
java.lang.RuntimeException: com.xiaozhou.common.domain.BusinessException: 对不起,您没有权限访问 com.xiaozhou.common.domain.BusinessException: 对不起,您没有权限访问 at com.xiaozhou.dynamic.api.ArticleApiImpl.queryArticleDtoByAuth(ArticleApiImpl.java:115) at org.apache.dubbo.common.bytecode.Wrapper2.invokeMethod(Wrapper2.java) at org.apache.dubbo.rpc.proxy.javassist.JavassistProxyFactory.doInvoke(JavassistProxyFactory.java:47) at org.apache.dubbo.rpc.proxy.AbstractProxyInvoker.invoke(AbstractProxyInvoker.java:84) at org.apache.dubbo.config.invoker.DelegateProvidermetaDataInvoker.invoke(DelegateProvidermetaDataInvoker.java:56) at org.apache.dubbo.rpc.protocol.InvokerWrapper.invoke(InvokerWrapper.java:56) at org.apache.dubbo.rpc.filter.ExceptionFilter.invoke(ExceptionFilter.java:55) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.monitor.support.MonitorFilter.invoke(MonitorFilter.java:92) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.TimeoutFilter.invoke(TimeoutFilter.java:48) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.protocol.dubbo.filter.TraceFilter.invoke(TraceFilter.java:81) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at com.xiaozhou.dynamic.filter.ExceptionFilter.invoke(ExceptionFilter.java:39) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.ContextFilter.invoke(ContextFilter.java:96) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.GenericFilter.invoke(GenericFilter.java:148) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.ClassLoaderFilter.invoke(ClassLoaderFilter.java:38) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.filter.EchoFilter.invoke(EchoFilter.java:41) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper.invoke(ProtocolFilterWrapper.java:82) at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$CallbackRegistrationInvoker.invoke(ProtocolFilterWrapper.java:157) at org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol.reply(DubboProtocol.java:152) at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.handleRequest(HeaderExchangeHandler.java:102) at org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler.received(HeaderExchangeHandler.java:193) at org.apache.dubbo.remoting.transport.DecodeHandler.received(DecodeHandler.java:51) at org.apache.dubbo.remoting.transport.dispatcher.ChannelEventRunnable.run(ChannelEventRunnable.java:57) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) at org.apache.dubbo.rpc.filter.ExceptionFilter$ExceptionListener.onResponse(ExceptionFilter.java:105) ~[dubbo-2.7.3.jar:2.7.3] at org.apache.dubbo.rpc.protocol.ProtocolFilterWrapper$CallbackRegistrationInvoker.lambda$invoke
原因分析:
一、查看服务端控制台输出错误日志如下:
ERROR 8216 --- [20001-thread-16] .d.r.f.ExceptionFilter$ExceptionListener : [DUBBO] Got unchecked and undeclared exception which called by 192.168.*.*. service: com.xiaozhou.dynamic.api.ArticleApi, method: queryArticleDtoByAuth, exception: com.xiaozhou.common.domain.BusinessException: 对不起,您没有权限访问, dubbo version: 2.7.3, current host: 192.168.*.*
二、查阅相关内容与源码分析
现象是dubbo的ExceptionFilter类将自定义异常封装成RuntimeException后抛出,上面消费端打印异常也可看出;然后下面为org.apache.dubbo.rpc.filter.ExceptionFilter中的onResponse源码分析结论。
1.异常类不是RuntimeException并且是Exception时,直接抛出
2.异常类是在方法签名上声明的抛出异常时,return 直接抛出
3.异常类和接口类在同一个jar包中时,直接抛出
4.异常类是如为"java."或"javax."开头的类名时(JDK的),直接抛出
5.异常类是dubbo自己的异常RpcException类时,直接抛出
6.其他,封装成RuntimeException类抛出
解决方案:
根据以上的原因可以对应方案:
1.自定义异常类改成Exception继承类,启动checked不通过,不太现实
2.在对应的服务接口方法上直接throw抛出自定义异常
3.将自定义异常与接口类放置同一个jar包中
4.重写dubbo的org.apache.dubbo.rpc.filter.ExceptionFilter,在dubbo服务端中如下 *** 作:
- 在springboot的配置文件中新加dubbo.provider.filter配置,配置为:customExceptionFilter,-exception
- 最后就是进行自定义类改造了,如下:
(1)直接判断如果为自定义异常类,直接return抛出
(2)直接判断如果为自定义异常类的类路径,直接return抛出
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)