Protobuf 由于默认而忽略 bool 和 ints 值
Protobuf ignoring bool and ints values due to default
我正在将 json 文件转换为字符串,然后将字符串转换为 proto3 文件。
这是 json 文件:
{ "a": false,
"b": 0
}
以下是我如何将 json 文件转换为字符串:
String json =Files.lines(Paths.get(filePath)).collect(Collectors.joining());
以下是我将字符串转换为 proto3 文件的方法:
JsonFormat.parser().ignoringUnknownFields().merge(json,messageBuilder);
MyProto proto = messageBuilder.build();
我的 json 中有 boolean 和 int 字段,其中一些值必须是默认值(boolean 为 false,int 为 0)。
当我将上述文件反序列化为 proto3 java 文件时,上述两个字段都将被忽略,并且我的 json 变为空,即使我已经明确设置了值(如您所见)在上面的 json 文件中)。
我知道 proto3 在 deserializing/serializing 时会忽略默认值,但是有什么方法可以不忽略显式设置的字段,即使它们是默认值?
不,Protobuf language guide 明确指出这是不可能的:
Note that for scalar message fields, once a message is parsed there's
no way of telling whether a field was explicitly set to the default
value (for example whether a boolean was set to false) or just not set
at all: you should bear this in mind when defining your message types.
For example, don't have a boolean that switches on some behaviour when
set to false if you don't want that behaviour to also happen by
default. Also note that if a scalar message field is set to its
default, the value will not be serialized on the wire.
如果您真的必须知道是否明确设置了默认值,您可以在单独的字段中对该信息进行编码。
使用 proto2 而不是 proto3 。 Proto2 有这种行为 - 如果一个字段被显式设置,即使它是该字段的默认值,它也会被序列化和反序列化。
我正在将 json 文件转换为字符串,然后将字符串转换为 proto3 文件。
这是 json 文件:
{ "a": false,
"b": 0
}
以下是我如何将 json 文件转换为字符串:
String json =Files.lines(Paths.get(filePath)).collect(Collectors.joining());
以下是我将字符串转换为 proto3 文件的方法:
JsonFormat.parser().ignoringUnknownFields().merge(json,messageBuilder);
MyProto proto = messageBuilder.build();
我的 json 中有 boolean 和 int 字段,其中一些值必须是默认值(boolean 为 false,int 为 0)。
当我将上述文件反序列化为 proto3 java 文件时,上述两个字段都将被忽略,并且我的 json 变为空,即使我已经明确设置了值(如您所见)在上面的 json 文件中)。
我知道 proto3 在 deserializing/serializing 时会忽略默认值,但是有什么方法可以不忽略显式设置的字段,即使它们是默认值?
不,Protobuf language guide 明确指出这是不可能的:
Note that for scalar message fields, once a message is parsed there's no way of telling whether a field was explicitly set to the default value (for example whether a boolean was set to false) or just not set at all: you should bear this in mind when defining your message types. For example, don't have a boolean that switches on some behaviour when set to false if you don't want that behaviour to also happen by default. Also note that if a scalar message field is set to its default, the value will not be serialized on the wire.
如果您真的必须知道是否明确设置了默认值,您可以在单独的字段中对该信息进行编码。
使用 proto2 而不是 proto3 。 Proto2 有这种行为 - 如果一个字段被显式设置,即使它是该字段的默认值,它也会被序列化和反序列化。