我正在运行一个项目,需要
- 不同编程语言之间的交互(主要是java, c++)。
- 可以序列化/反序列化为二进制格式和json格式。
- IDL生成不同语言的类代码
byte[] data = recv();
Object object = TDeserializer.deserialize(data);
if (object instanceof TypeA) {
TypeA a = (TypeA) object;
} else if (object instanceof TypeB) {
TypeB b = (TypeB) object;
}
似乎我们必须告诉thrift它需要反序列化成哪个结构体,比如:
byte[] data = recv();
TypeA a;
TDeserializer.deserialize(a, data);
只是想知道是否有一种方法可以在不知道其确切类型的情况下将原始数据反序列化为thrift对象。
谢谢! !
Thrift序列化消息本身不包含类型信息,因此反序列化器必须知道消息的数据类型。但是,可以将所有必要的数据类型包装到union中。
节俭代码:union Message {
1: TypeA a;
2: TypeB b;
}
反序列化代码:
byte[] data = recv();
Message msg;
TDeserializer.deserialize(msg, data);
<find out message type with msg.getSetField()>
如果需要添加新的消息类型,只需在union中添加另一个字段。如果不修改旧的字段id,将保留向后兼容性:
union Message {
1: TypeA a;
2: TypeB b;
3: TypeC c; <-- OK
}
您将能够接收来自旧生产者的消息(他们永远不会发送TypeC
消息),并向旧消费者发送TypeA
/TypeB
消息。如果您将TypeC
消息发送给不知道字段#3的消费者,它将获得异常。
这种方法的最大优点是类型信息非常紧凑。如果您使用TCompactProtocol
,类型info在大多数情况下只会占用1个额外的字节(如果Message
中的字段id小于127)。
要小心,如果更改字段id,将失去向后兼容性。例如:
union Message {
1: TypeA a;
2: TypeC c; <-- Wrong
3: TypeB b; <-- Wrong
4: TypeD d; <-- OK
}