【Soul源码阅读-04】sofa插件初体验

目标

  • 运行examples下面的 sofa-rpc 服务
  • 学习文档,结合 sofa 插件,发起 http 请求 soul 网关,体验 sofa 代理

soul 网关接入 sofa 应用

  • 参考官方文档:https://dromara.org/zh-cn/doc...

    • 引入相关依赖

      soul-bootstrap新增如下依赖:

            
                 com.alipay.sofa
                 sofa-rpc-all
                 5.7.6
             
             
                 org.apache.curator
                 curator-client
                 4.0.1
             
             
                 org.apache.curator
                 curator-framework
                 4.0.1
             
             
                 org.apache.curator
                 curator-recipes
                 4.0.1
             
             
                 org.dromara
                 soul-spring-boot-starter-plugin-sofa
                 2.2.1
             

      soul-examples-sofa新增如下依赖:

      
                
            org.dromara
                  soul-spring-boot-starter-client-sofa
                  2.2.1
                  
                      
                          guava
                          com.google.guava
                      
                  
              
    • application.yml添加相关配置

      soul:
        sofa:
          adminUrl: http://localhost:9095
          contextPath: /sofa
          appName: sofa
            # adminUrl: 为你启动的 soul-admin 项目的ip + 端口,注意要加 http://
            # contextPath: 为你的这个项目在soul网关的路由前缀,比如/order ,/product 等等,网关会根据你的这个前 缀来进行路由.
            # appName:你的应用名称,不配置的话,会默认取 sofa 配置中application 中的名称
  • sofa 插件设置

    soul-admin 插件管理中,sofa 插件设置为开启
    【Soul源码阅读-04】sofa插件初体验_第1张图片

  • 接口注册到网关

    • sofa 服务实现类的方法上加上 @SoulSofaClient 注解,表示该接口方法注册到网关
  • 先启动zk,然后再启动TestSofaApplication,输出日志 init sofa client reference success,表示sofa接口已经发布到 soul 网关
    image-20210118210828

sofa 用户请求以及参数说明

sofa 参数传递方式:

  • 通过 http post 方式访问网关,通过body,json类型传递
  • 单个java bean参数类型 (默认)
  • 自定义实现多参数支持:

    • 在你搭建的网关项目中,新增一个类 A,实现 org.dromara.soul.plugin.api.sofa.SofaParamResolveService

      public interface SofaParamResolveService {
             /**
              * Build parameter pair.
              * this is Resolve http body to get sofa param.
              *
              * @param body           http中body传的json字符串 
              * @param parameterTypes 匹配到的方法参数类型列表,如果有多个,则使用,分割
              * @return pair left为参数类型,right为参数值
              */
             Pair buildParameter(String body, String parameterTypes);
         }
  • 通过 http post 方式访问网关,通过body,json类型传递
  • 【Soul源码阅读-04】sofa插件初体验_第2张图片

使用 http post 方式访问,后台NullPointerException
【Soul源码阅读-04】sofa插件初体验_第3张图片

打断点,调试

         GenericService genericService = reference.refer();
        Pair pair;
        if (null == body || "".equals(body) || "{}".equals(body) || "null".equals(body)) {
            pair = new ImmutablePair<>(new String[]{}, new Object[]{});
        } else {
            // body 不为空
            pair = sofaParamResolveService.buildParameter(body, metaData.getParameterTypes());
        }

body 不为空时,调用了sofaParamResolveService.buildParameter(String body, String parameterTypes)方法,但在官方介绍中,只有自定义实现多参数支持才需要实现org.dromara.soul.plugin.api.sofa.SofaParamResolveService类,不知道这块是不是个BUG。代码中搜了搜,发现只在SofaProxyServiceTest类中以静态内部类方式实现了`sofaParamResolveService

【Soul源码阅读-04】sofa插件初体验_第4张图片

先实现下`sofaParamResolveService试下结果

public Pair buildParameter(final String body, final String parameterTypes) {
        Map paramMap = GsonUtils.getInstance().toObjectMap(body);
        String[] parameter = StringUtils.split(parameterTypes, ",");
        if (parameter.length == 1 && !isBaseType(parameter[0])) {
            for (String key : paramMap.keySet()) {
                Object obj = paramMap.get(key);
                if (obj instanceof JsonObject) {
                    paramMap.put(key, GsonUtils.getInstance().convertToMap(obj.toString()));
                } else if (obj instanceof JsonArray) {
                    paramMap.put(key, GsonUtils.getInstance().fromList(obj.toString(), Object.class));
                } else {
                    paramMap.put(key, obj);
                }
            }
            return new ImmutablePair<>(parameter, new Object[]{paramMap});
        }
        List list = new LinkedList<>();
        for (String key : paramMap.keySet()) {
            Object obj = paramMap.get(key);
            if (obj instanceof JsonObject) {
                list.add(GsonUtils.getInstance().convertToMap(obj.toString()));
            } else if (obj instanceof JsonArray) {
                list.add(GsonUtils.getInstance().fromList(obj.toString(), Object.class));
            } else {
                list.add(obj);
            }
        }
        Object[] objects = list.toArray();
        return new ImmutablePair<>(parameter, objects);
    }

    private boolean isBaseType(final String paramType) {
        return paramType.startsWith("java") || paramType.startsWith("[Ljava");
    } 
 

再次运行,成功:
【Soul源码阅读-04】sofa插件初体验_第5张图片

主要了解了一下 soul 网关接入 Sofa 应用,使用各种请求参数通过 http 请求 soul 网关,体验 sofa 代理。

你可能感兴趣的:(Soul)