目标
- 运行examples下面的 sofa-rpc 服务
- 学习文档,结合 sofa 插件,发起 http 请求 soul 网关,体验 sofa 代理
soul 网关接入 sofa 应用
参考官方文档:https://dromara.org/zh-cn/doc...
引入相关依赖
soul-bootstrap
新增如下依赖:<dependency> <groupId>com.alipay.sofa</groupId> <artifactId>sofa-rpc-all</artifactId> <version>5.7.6</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-client</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-plugin-sofa</artifactId> <version>2.2.1</version> </dependency>
soul-examples-sofa
新增如下依赖:<dependency> <groupId>org.dromara</groupId> <artifactId>soul-spring-boot-starter-client-sofa</artifactId> <version>2.2.1</version> <exclusions> <exclusion> <artifactId>guava</artifactId> <groupId>com.google.guava</groupId> </exclusion> </exclusions> </dependency>
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
插件设置为开启sofa
插件中配置你的注册地址 接口注册到网关
- sofa 服务实现类的方法上加上
@SoulSofaClient
注解,表示该接口方法注册到网关
- sofa 服务实现类的方法上加上
- 先启动
zk
,然后再启动TestSofaApplication
,输出日志init sofa client reference success
,表示sofa
接口已经发布到 soul 网关
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<String[], Object[]> buildParameter(String body, String parameterTypes); }
- 通过 http post 方式访问网关,通过body,json类型传递
使用 http post 方式访问,后台NullPointerException
打断点,调试
GenericService genericService = reference.refer();
Pair<String[], Object[]> 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
先实现下`sofaParamResolveService
试下结果
public Pair<String[], Object[]> buildParameter(final String body, final String parameterTypes) {
Map<String, Object> 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<Object> 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 网关接入 Sofa 应用,使用各种请求参数通过 http 请求 soul 网关,体验 sofa 代理。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。