来自 json 的原型反序列化将在新字段或未知枚举值上失败

Posted

技术标签:

【中文标题】来自 json 的原型反序列化将在新字段或未知枚举值上失败【英文标题】:Proto deserialization from json will fail on new fields or unknown enum values 【发布时间】:2016-05-31 04:47:34 【问题描述】:

proto 旨在引入新字段不会破坏您在旧版本上运行的代码。

但是,如果您在 java 中使用 json 转换,使用 protobuf-java-util,那么您的旧代码将在新字段或现有代码未知的新枚举值上中断...

我在github 上打开了issue,但没有引起任何注意。我希望在这里得到一些答案。

给定这样的消息

message Msg 
    required string sender = 1;
    required string message = 2;

如果我们将其转换为 json 并使用

打印
JsonFormat.printer().print(msg)

我们会得到这个结果


  "sender": "me",
  "message": "message"

如果我们使用其构建器将此 json 解码为 Msg

JsonFormat.parser().merge(json, builder)

我们会得到预期的结果...但是如果我们尝试使用额外的extra 字段解码类似的json


  "sender": "me",
  "message": "message",
  "extra" : "some extra stuff"

我们会因为这个异常而失败

com.google.protobuf.InvalidProtocolBufferException: Cannot find field: extra in message proto.Msg

怎么没人关心这个问题?到目前为止,我对此的唯一解决方案是从头开始编写一个解析器,在解析时将忽略未知字段和未知枚举值......

是否有什么我忽略了或人们根本不使用向后兼容功能?

【问题讨论】:

到目前为止我从未使用过 json 格式,但我同意忽略未知字段更有意义。这也是大多数其他接受 json 的程序的行为方式,以及它与二进制 protobuf 一起工作的方式。 【参考方案1】:

谷歌已经修复了这个问题,构建器提供了忽略未知字段的选项。

【讨论】:

您能否具体说明如何做到这一点?我找不到任何文档 阅读我创建的原始问题中的问题,在将字符串 json 解析为 proto 时,您会创建一个像这样的实例 JsonFormat.parser().ignoringUnknownFields().merge(json, yourBuilder) ignoringUnknownFields() 是修复

以上是关于来自 json 的原型反序列化将在新字段或未知枚举值上失败的主要内容,如果未能解决你的问题,请参考以下文章

使用已知和未知字段反序列化 json

如何使用 Jackson json 注释枚举字段以进行反序列化

如果已删除枚举项,则将Json反序列化回列表或枚举会导致错误[重复]

使用 Jackson 处理未知的 JSON 属性

Jackson 将额外字段反序列化为 Map

当对象数量未知时反序列化Json