如何处理Java中未知的protobuf字段?

时间:2019-05-11 13:39:41

标签: java protocol-buffers protobuf-java

我有一个Java应用程序,可以从另一台计算机读取一些protobuf数据,然后可以修改一些值并将其写回。用户很可能可以使用过时的.proto文件读取数据,因此在这种情况下会有一些它无法理解的字段。我最终希望在回写所做的更改时保留未知数据;但是,我可以解决一下,只是检测到有未知数据(以提示用户升级他/她的应用程序)。我不清楚如何处理Java中的未知字段。

如果有帮助,我正在使用版本2 .proto文件,因为我需要它与远程计算机上的nanopb兼容。

这个question可以帮助我,但是我的问题与JSON无关。

1 个答案:

答案 0 :(得分:2)

首先,当您说未知字段时请注意。在protobuf中,根据定义,您可以具有未知字段,但另一方面-我想这是您的情况-您可以在当前的proto文件中拥有一些您没有的字段。

在两种情况下,您都可以轻松访问值。假设您有一条名为 foo 的原始消息。

您必须访问描述符并按名称从那里获取字段,最后获得如下所示的值:

Builder builder = foo.toBuilder();
FieldDescriptor field = builder.getDescriptorForType().findFieldByName("whatever field");
Object obj = builder.getField(field);

// if your field is int32 cast to int
int value = (int) obj

如果您想输入'unknown'值,则可以采用其他方法:

Builder builder = foo.toBuilder();
FieldDescriptor field = builder.getDescriptorForType().findFieldByName("whatever field");
builder.setField(field, 100); // 100 is an example int value
Foo foo = builder.build();

如果您真的想插入原型定义的未知字段,则必须执行以下操作:

 UnknownFieldSet.Field seqField = UnknownFieldSet.Field
            .newBuilder()
            .addFixed32(100) // 100 is an example int value
            .build();

 UnknownFieldSet unkFieldSet = UnknownFieldSet
            .newBuilder()
            .addField(99, seqField) // 99 is a proto index number chosen by me
            .build();

 Foo message = foo.toBuilder().setUnknownFields(unkFieldSet).build();

再次通过以下操作读取定义的未知字段:

 foo.toBuilder().getUnknownFields()....

我希望这会有所帮助。