【发布时间】:2011-08-26 10:15:19
【问题描述】:
协议缓冲区Java tutorial 声明:
协议消息类提供的一个关键特性是反射。 [...] 使用反射的一种非常有用的方法是将协议消息与其他编码(例如 XML 或 JSON)相互转换。
如果您查看com.google.protobuf.Message,它会说:
[Message 类相对于 MessageLite 类的最大附加功能] 是自省和反射。
这似乎表明协议缓冲区已准备好与许多现有的基于 Java 反射的序列化库一起使用,但实际上我认为它们并不是指传统 Java 意义上的反射。
例如如果我尝试使用 XStream(一个使用反射将 Java 对象序列化为 XML 的流行库)序列化我的协议缓冲区消息之一,我会得到:
<com.x.MyProtos_-MyMessage resolves-to="com.google.protobuf.GeneratedMessageLite$SerializedForm">
<messageClassName>com.x.MyProtos$MyMessage</messageClassName>
<asBytes>CjkKDkJXQkUwMDAzNzkzMTA3EgsZAAAAAAAA8D8gASIGEJYBGMIDKhIpuB6F61G4nj8xuB6F61G4
Xnj8KMQoGQURBQkliEgsZAAAAAAAA8D8gASIGEJYBGMIDKhIpuB6F61G4nj8xuB6F61G4nj8qAyDQ
Dw==</asBytes>
[我注意到 XML 提到 GeneratedMessageLite,即 MessageLite 的子类,即使被序列化的实例是 com.google.protobuf.Message 的实例]
我发现将协议缓冲区序列化为 XML 的唯一现有解决方案(这样结果在某种程度上是人类可读的)是 protobuf-java-format。
这会产生很好的输出 - 但是因为它不输出标签值,即字段的数字 id。因此,在反序列化方面,生成的 XML 看起来并不是非常健壮,即据我所知,如果您更改字段名称,但使用标准协议缓冲区序列化,事情将继续正常工作,但保留标签值相同,然后尝试反序列化在这些更改之前序列化的字节序列。
有没有人遇到过一种 XML 序列化解决方案,它保留了协议缓冲区的大部分吸引人的特性(只是序列化时间变慢和生成的消息更大)?
或者想出如何利用现有流行的 Java XML 序列化库之一来利用协议缓冲区的“反射”特性?
问候,
/乔治
PS 如果您想知道我为什么要序列化为 XML,那是因为我想要一种便宜的(在编程术语中)在某些情况下手动编辑消息的方法。
【问题讨论】:
标签: java reflection xml-serialization protocol-buffers