答案可能有点晚了,但也许这仍然对某人有所帮助。
在当前版本的 Protocol Buffers 3 中,pack 和 unpack 是 available in Java。
在您的示例中,包装可以这样完成:
Any anyMessage = Any.pack(protoMess.build()));
然后像这样解包:
ProtoMess protoMess = anyMessage.unpack(ProtoMess.class);
这里也是处理带有嵌套Any消息的Protocol Buffers消息的完整示例:
ProtocolBuffers 文件
带有嵌套Any 消息的简单协议缓冲区文件可能如下所示:
syntax = "proto3";
import "google/protobuf/any.proto";
message ParentMessage {
string text = 1;
google.protobuf.Any childMessage = 2;
}
一个可能的嵌套消息可能是:
syntax = "proto3";
message ChildMessage {
string text = 1;
}
包装
要构建完整的消息,可以使用以下函数:
public ParentMessage createMessage() {
// Create child message
ChildMessage.Builder childMessageBuilder = ChildMessage.newBuilder();
childMessageBuilder.setText("Child Text");
// Create parent message
ParentMessage.Builder parentMessageBuilder = ParentMessage.newBuilder();
parentMessageBuilder.setText("Parent Text");
parentMessageBuilder.setChildMessage(Any.pack(childMessageBuilder.build()));
// Return message
return parentMessageBuilder.build();
}
开箱
要从父消息中读取子消息,可以使用以下函数:
public ChildMessage readChildMessage(ParentMessage parentMessage) {
try {
return parentMessage.getChildMessage().unpack(ChildMessage.class);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
return null;
}
}
编辑:
如果您打包的消息可以有不同的类型,您可以读出typeUrl 并使用反射来解包消息。假设您有子消息 ChildMessage1 和 ChildMessage2,您可以执行以下操作:
@SuppressWarnings("unchecked")
public Message readChildMessage(ParentMessage parentMessage) {
try {
Any childMessage = parentMessage.getChildMessage();
String clazzName = childMessage.getTypeUrl().split("/")[1];
String clazzPackage = String.format("package.%s", clazzName);
Class<Message> clazz = (Class<Message>) Class.forName(clazzPackage);
return childMessage.unpack(clazz);
} catch (ClassNotFoundException | InvalidProtocolBufferException e) {
e.printStackTrace();
return null;
}
}
为了进一步处理,可以用instanceof判断消息的类型,效率不高。如果要获取某种类型的消息,应该直接比较typeUrl:
public ChildMessage1 readChildMessage(ParentMessage parentMessage) {
try {
Any childMessage = parentMessage.getChildMessage();
String clazzName = childMessage.getTypeUrl().split("/")[1];
if (clazzName.equals("ChildMessage1")) {
return childMessage.unpack("ChildMessage1.class");
}
return null
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
return null;
}
}