Java环境下ByteBuf通过CBOR及ProtobufSchemaLoader解析的问题咨询
生成符合要求的protobuf_str的方案
核心说明
ProtobufSchemaLoader.std.parse方法接收的参数是标准Protobuf IDL文本,你需要生成和现有Java类结构匹配的proto定义文本作为入参。
步骤1:编写匹配类结构的Proto IDL
根据你给出的Payload、Data类结构,对应Proto定义如下:
syntax = "proto3"; // 导入Any类型定义,用来对应Java中的Object类型 import "google/protobuf/any.proto"; // 对应Java的Data类 message Data { // 对应Map<Integer, Object>,int32匹配Integer,Any匹配任意类型的value map<int32, google.protobuf.Any> data = 1; } // 对应Java的Payload类 message Payload { // 对应Map<Date, Data>,Date转成毫秒时间戳用int64存储,value为Data类型 map<int64, Data> dataArray = 1; }
如果你明确知道Data类的Map中value的可能类型,也可以用oneof替代Any减少解析开销,示例如下:
message DataValue { oneof value { int32 int_val = 1; string str_val = 2; bool bool_val = 3; double double_val = 4; } } message Data { map<int32, DataValue> data = 1; }
步骤2:转成Java可用的protobuf_str
把上面的IDL转义成Java字符串即可,示例代码:
String protobuf_str = "syntax = \"proto3\";\n" + "import \"google/protobuf/any.proto\";\n" + "message Data {\n" + " map<int32, google.protobuf.Any> data = 1;\n" + "}\n" + "message Payload {\n" + " map<int64, Data> dataArray = 1;\n" + "}";
解析ByteBuf的注意事项
- CBOR解析:直接读取ByteBuf的字节数组,用CBOR序列化工具直接反序列化为Payload对象即可
- Protobuf解析:传入上面的protobuf_str拿到schema后,配合Protobuf解码器读取ByteBuf字节流,注意要做两个类型转换:
- Payload中map的int64类型key转成Date:
new Date(longKey) - Data中map的Any类型value调用
unpack()方法转成实际对应的Java类型
- Payload中map的int64类型key转成Date:
- 必须保证ByteBuf中的二进制数据和你定义的Proto IDL字段号、类型完全匹配,否则会出现解析乱码或者失败的问题
内容的提问来源于stack exchange,提问作者רואד מנסור
相关产品推荐
相关产品推荐

