apache dubbo 实现自定义异常拦截器

有朋友反馈apache dubbo 按照上一篇博客配置不生效,本文结合上一篇文章讲解一下apache dubbo(version = 2.7.5) 配置 与 alibaba dubbo 配置的区别以及解决思路

1.yum文件配置

在这里插入图片描述

exceptionFilter 为我们配置的异常拦截器,-exception为取消默认拦截器【必须设置否则不生效】

2.配置exceptionFilter

在这里插入图片描述
与之前对比,resoures 下文件夹变更及文件名变更

3.创建AyaDubboExceptionFilter类

@Activate(group = CommonConstants.PROVIDER)
public class AyaDubboExceptionFilter implements Filter, Filter.Listener {
    private Logger logger = LoggerFactory.getLogger(ExceptionFilter.class);

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        return invoker.invoke(invocation);
    }

    @Override
    public Result onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
            try {
                Throwable exception = appResponse.getException();

                // directly throw if it's checked exception
                if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
                    return appResponse;
                }
                // directly throw if the exception appears in the signature
                try {
                    Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
                    Class<?>[] exceptionClassses = method.getExceptionTypes();
                    for (Class<?> exceptionClass : exceptionClassses) {
                        if (exception.getClass().equals(exceptionClass)) {
                            return appResponse;
                        }
                    }
                } catch (NoSuchMethodException e) {
                    return appResponse;
                }

                // for the exception not found in method's signature, print ERROR message in server's log.
                logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);

                // directly throw if exception class and interface class are in the same jar file.
                String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
                String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
                if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
                    return appResponse;
                }
                // directly throw if it's JDK exception
                String className = exception.getClass().getName();
                if (className.startsWith("java.") || className.startsWith("javax.")) {
                    return appResponse;
                }
                // directly throw if it's dubbo exception
                if (exception instanceof RpcException) {
                    return appResponse;
                }

                if (exception instanceof YtException) {
                    logger.debug("ytException");
                    YtException rrException = (YtException) exception;
                    appResponse.setException(rrException);
                    return appResponse;
                }
                // otherwise, wrap with RuntimeException and throw back to the client
                appResponse.setException(new RuntimeException(StringUtils.toString(exception)));
            } catch (Throwable e) {
                logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
            }
        }
        return appResponse;
    }

    @Override
    public void onMessage(Result result, Invoker<?> invoker, Invocation invocation) {

    }

    @Override
    public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
        logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
    }

    // For test purpose
    public void setLogger(Logger logger) {
        this.logger = logger;
    }


}

其中自己需要变更部分,此处写自己需要设定的自定义异常

 if (exception instanceof YtException) {
                    logger.debug("ytException");
                    YtException rrException = (YtException) exception;
                    appResponse.setException(rrException);
                    return appResponse;
                }

总结

解决思路,面对dubbo不同的版本号,也许处理方式会不一致
1.首先需对dubbo内部异常处理需要有一定的了解, 下载dubbo源码
2.
在这里插入图片描述在这里插入图片描述

通过阅读源码,我们会发现消费者无法接收自定义原因如下:

appResponse.setException(new RuntimeException(StringUtils.toString(exception)));

dubbo将其他异常信息,统一转化为运行时异常,所以我们的处理思路就是在此前判断我们系统自定义异常,直接返回,处理如第三步

上一篇:dubbo 2.6.X 自定义异常处理

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值