将 Jason 反序列化为 ProtoBuffer 时消息空值设置为默认值

When deserializing Jason to ProtoBuffer message null values set to default values

我正在使用 ProtoBuffer 3,我有一条消息由多个字段组成,其中一些是包含一些(或全部)可为空值的其他消息。

例如:

message MainMessage {
   google.protobuf.StringValue title = 1;
   NotNullable sub1 = 2;
   Nullable sub2 = 3;
   NotNullable sub3 = 4;
}

message NotNullable {
    int64 id = 1;
    string value = 2;
}

message Nullable {
    google.protobuf.Int64Value id = 1;
    google.protobuf.Int64Value value = 2;
}

我作为儿子收到消息,我想使用以下代码反序列化它:

String json = "{\"title\":{\"value\":\"A nice title\"},\"sub1\":{\"id\":{\"value\":1}}}";
MainMessage.Builder message = MainMessage.newBuilder();
JsonFormat.parser().merge(json, message);

在 运行 之后,我得到的对象上方的代码包含所有字段(即使 sub2sub3 不在 JSON 中)其中缺失数据初始化为默认值。

例如,下面的代码会return为真:

assertTrue(message.getSub2().getId().isInitialized())
assertTrue(message.getSub3().isInitialized())

我查看了文档,但找不到告诉解析器不要设置这些字段的方法 - 有这样的选项吗?

这篇文章似乎解决了这个问题:https://itnext.io/protobuf-and-null-support-1908a15311b6

我实现它的方式如下(抱歉混淆了名称 - 我想保留原来的名称):

message MainMessage {
   google.protobuf.StringValue title = 1;
   NotNullable sub1 = 2;
   Nullable sub2 = 3;
   NotNullable sub3 = 4;
}

message NotNullable {
    int64 id = 1;
    string value = 2;
}

message Nullable {
    google.protobuf.Int64Value id = 1;
    google.protobuf.Int64Value value = 2;
}

message AllowNullable {
    oneof kind {
       google.protobuf.NullValue null = 1;
       Nullable value = 2;
}

现在只需要在调用该值之前使用has方法来检查它是否为空

例如:

if(message.getSub3().hasValue()) {
   // do something...
}