GoogleProtobuf 对象泛化调用

对 Google Protobuf 对象进行泛化调用

泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参考 泛化调用。 一般泛化调用只能用于生成的服务参数为POJO的情况,而 GoogleProtobuf 的对象是基于 Builder 生成的非正常POJO,可以通过 protobuf-json 泛化调用。

GoogleProtobuf 序列化相关的Demo可以参考 protobuf-demo

通过Spring对Google Protobuf对象泛化调用

在 Spring 中配置声明 generic = “protobuf-json”

  1. <dubbo:reference id="barService" interface="com.foo.BarService" generic="protobuf-json" />

在 Java 代码获取 barService 并开始泛化调用:

  1. GenericService barService = (GenericService) applicationContext.getBean("barService");
  2. Object result = barService.$invoke("sayHello",new String[]{"org.apache.dubbo.protobuf.GooglePbBasic$CDubboGooglePBRequestType"}, new Object[]{"{\"double\":0.0,\"float\":0.0,\"bytesType\":\"Base64String\",\"int32\":0}"});

通过 API 方式对 Google Protobuf 对象泛化调用

  1. ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
  2. // 弱类型接口名
  3. reference.setInterface(GenericService.class.getName());
  4. reference.setInterface("com.xxx.XxxService");
  5. // 声明为Protobuf-json
  6. reference.setGeneric(Constants.GENERIC_SERIALIZATION_PROTOBUF);
  7. GenericService genericService = reference.get();
  8. Map<String, Object> person = new HashMap<String, Object>();
  9. person.put("fixed64", "0");
  10. person.put("int64", "0");
  11. // 参考google官方的protobuf 3 的语法,服务的每个方法中只传输一个POJO对象
  12. // protobuf的泛化调用只允许传递一个类型为String的json对象来代表请求参数
  13. String requestString = new Gson().toJson(person);
  14. // 返回对象是GoolgeProtobuf响应对象的json字符串。
  15. Object result = genericService.$invoke("sayHello", new String[] {
  16. "com.xxx.XxxService.GooglePbBasic$CDubboGooglePBRequestType"},
  17. new Object[] {requestString});

GoogleProtobuf 对象的处理

GoogleProtobuf 对象是由 Protocol 契约生成,相关知识请参考 ProtocolBuffers 文档。假如有如下Protobuf 契约

  1. syntax = "proto3";
  2. package com.xxx.XxxService.GooglePbBasic.basic;
  3. message CDubboGooglePBRequestType {
  4. double double = 1;
  5. float float = 2;
  6. int32 int32 = 3;
  7. bool bool = 13;
  8. string string = 14;
  9. bytes bytesType = 15;
  10. }
  11. message CDubboGooglePBResponseType {
  12. string msg = 1;
  13. }
  14. service CDubboGooglePBService {
  15. rpc sayHello (CDubboGooglePBRequestType) returns (CDubboGooglePBResponseType);
  16. }

则对应请求按照如下方法构造

  1. Map<String, Object> person = new HashMap<>();
  2. person.put("double", "1.000");
  3. person.put("float", "1.00");
  4. person.put("int32","1" );
  5. person.put("bool","false" );
  6. //String 的对象需要经过base64编码
  7. person.put("string","someBaseString");
  8. person.put("bytesType","150");

GoogleProtobuf 服务元数据解析

Google Protobuf 对象缺少标准的 JSON 格式,生成的服务元数据信息存在错误。请添加如下依赖元数据解析的依赖。

  1. <dependency>
  2. <groupId>org.apache.dubbo</groupId>
  3. <artifactId>dubbo-metadata-definition-protobuf</artifactId>
  4. <version>${dubbo.version}</version>
  5. </dependency>

从服务元数据中也可以比较容易构建泛化调用对象。

最后修改 September 21, 2021: Bug fix miss mialbox (#953) (57cf51b)