springcloud整合dubbo结构

整体架构:

 

请求传递流程:

 

可以看到请求是a -> b -> c跳了两层的,所以http请求中附带的token等请求头参数无法在provider中直接获取,换言之,token只能在controller层获取,而不能在service层获取

为了解决这个问题,可以配置消费者拦截器:

package com.gdcx.web.filter;


import com.gdcx.constants.Constant;
import com.gdcx.utils.UserClientUtil;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

@Activate(group = {CommonConstants.CONSUMER}, order = Integer.MIN_VALUE)
public class DubboConsumerParamsFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        RpcServiceContext context = RpcContext.getServiceContext();
        context.setObjectAttachment(Constant.TOKEN_HEADER, UserClientUtil.getCurrentToken());//消费者带上token请求
        return invoker.invoke(invocation);
    }
}

 

此外为了方便,还可以配置异常处理器拦截器:

package com.gdcx.web.filter;

import com.gdcx.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.BaseFilter.Listener;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;

import java.lang.reflect.Method;

@Activate(group = {CommonConstants.PROVIDER})
@Slf4j
public class DubboExceptionFilter  implements Filter, Listener {

    public DubboExceptionFilter() {
    }

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

    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
            try {
                Throwable exception = appResponse.getException();
                if (!(exception instanceof RuntimeException) && exception instanceof Exception) {
                    return;
                }

                try {
                    Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
                    Class<?>[] exceptionClasses = method.getExceptionTypes();
                    Class[] var7 = exceptionClasses;
                    int var8 = exceptionClasses.length;

                    for(int var9 = 0; var9 < var8; ++var9) {
                        Class<?> exceptionClass = var7[var9];
                        if (exception.getClass().equals(exceptionClass)) {
                            return;
                        }
                    }
                } catch (NoSuchMethodException var11) {
                    return;
                }

                log.error("5-36", "", "", "Got unchecked and undeclared exception which called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);

                String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
                String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
                if (serviceFile != null && exceptionFile != null && !serviceFile.equals(exceptionFile)) {
                    String className = exception.getClass().getName();

                    if (!className.startsWith("java.") && !className.startsWith("javax.")) {
                        if (exception instanceof RpcException) {
                            return;
                        }
                        if (exception instanceof ServiceException) {
                            return;
                        }


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

                    return;
                }

                return;
            } catch (Throwable var12) {
                log.warn("5-36", "", "", "Fail to ExceptionFilter when called by " + RpcContext.getServiceContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + var12.getClass().getName() + ": " + var12.getMessage(), var12);
            }
        }

    }

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

}

 

最后,将两个拦截器放入请求中

路径:

 

代码:

dubboConsumerParamsFilter=com.gdcx.web.filter.DubboConsumerParamsFilter
exception=com.gdcx.web.filter.DubboExceptionFilter

 

posted @ 2023-06-27 19:58  fnasklf  阅读(14)  评论(0编辑  收藏  举报