springboot dubbo3 学习-全局异常处理过滤器

2025-01-22  本文已影响0人  草祭木初

版本
spring boot: 3.4.1
dubbo:3.3.1
java17

官方文档

1,过滤器代码


import jakarta.validation.ValidationException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;
import org.springframework.validation.BindException;

/**
 * dubbo统一异常处理过滤器
 */
@Slf4j
@Activate(group = {CommonConstants.PROVIDER}, order = 1)
public class ExceptionFilter implements Filter, Filter.Listener {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        Result appResponse;
        try {
            appResponse = invoker.invoke(invocation);
        } catch (Throwable e) {
            appResponse = AsyncRpcResult.newDefaultAsyncResult(e, invocation);
            onResponse(appResponse, invoker, invocation);
        }

        return appResponse;
    }

    @Override
    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        Throwable exception = appResponse.getException();
        if (exception != null) {
            log.info("Dubbo统一异常处理过滤器");

            // 取得底层真实异常
            // 异步线程异常 是包装过的
            // 在dubbo自带ExceptionFilter 包装过某些异常
            while (exception != null) {
                if (exception.getCause() != null) {
                    exception = exception.getCause();
                } else {
                    break;
                }
            }

            appResponse.setException(null);

            if(exception instanceof ValidationException ve) {
                // 参数校验异常
                appResponse.setValue(GlobalExceptionHandler.getValidExceptionMsg(ve));
            } else if (exception instanceof BindException e) {
                // 参数校验异常
                appResponse.setValue(GlobalExceptionHandler.getBindExceptionMsg(e));
            } else if (exception instanceof BizException e) {
                // 业务自定义异常
                appResponse.setValue(e.getRpcResult());
            } else if (exception instanceof Exception e) {
                appResponse.setValue(GlobalExceptionHandler.exceptionHandler(e));
            }
        }
    }

    @Override
    public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {

    }
}


说明:

2,配置文件

dubbo:
  protocol:
    name: tri
    port: 10003
  provider:
    export: true
    filter:
      - "loginAuthFilter,exceptionFilter"
      #- "-exception"
    validation: true

  consumer:
    #关闭服务检查 如果依赖的服务挂了 不影响调用
    check: false
    timeout: 300
    # 负载均衡策略 默认random(加权随机) 修改成轮询
    loadbalance: roundrobin
    # 重试次数 根据服务provider端服务器数量决定 用于查询场景
    # 事务场景要设置为0
    retries: 0
    validation: true
    # 集群容错模式 立即失败 用于事务模式
    cluster: failfast

说明

3,org.apache.dubbo.rpc.Filter 文件

位置

src
 |-main
    |-java
        |-com
            |-xxx
                |-XxxFilter.java (实现Filter接口)
    |-resources
        |-META-INF
            |-dubbo
                |-org.apache.dubbo.rpc.Filter (纯文本文件,内容为:xxx=com.xxx.XxxFilter)

内容

loginAuthFilter=com.zx.frame.filter.LoginAuthFilter
exceptionFilter=com.zx.frame.filter.ExceptionFilter

至此,自定义过滤器完成

4,问题与注意点

具体请参照官方文档(有解决方案):https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/security/class-check/
https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/serialization/serialization/

我采用的是比较极端的解决方案:关掉这个检查

dubbo.application.serialize-check-status=DISABLE
上一篇 下一篇

猜你喜欢

热点阅读