分类:proto| 发布时间:2025-01-17 22:32:00
介绍如何使用Protobuf到JSON转换实用程序。
Protobuf 支持在 JSON 中进行标准化编码,使得与不支持标准 Protobuf 二进制传输格式的系统共享数据变得更加容易。
ProtoJSON 格式没有 protobuf 二进制传输格式那么高效。 转换器在编码和解码消息时会消耗更多的 CPU 资源,并且(除非在极少数情况下)编码后的消息会占用更多空间。 此外,ProtoJSON 格式会将字段和枚举值的名称包含在编码的消息中,这使得稍后修改这些名称变得更加困难。 移除字段会导致破坏性更改,触发解析错误。 简而言之,有很多充分的理由,为什么 Google 更倾向于使用标准的二进制传输格式而非 ProtoJSON 格式。
编码方式将在本主题后面的表格中按类型逐一描述。
当将 JSON 编码的数据解析为 protocol buffer 时,如果某个值缺失或其值为 null
,它将被解释为相应的默认值。
当从 protocol buffer 生成 JSON 编码的输出时,如果某个 protobuf 字段具有默认值,并且该字段不支持字段存在性(field presence),则默认情况下该字段将被省略在输出中。 实现可能提供选项,以便在输出中包含具有默认值的字段。
具有设置值并支持字段存在性的字段,始终会在 JSON 编码的输出中包含字段值,即使它是默认值。
例如,一个使用 optional
关键字定义的 proto3 字段支持字段存在性,如果已设置,它将始终出现在 JSON 输出中。
任何版本的 protobuf 中的消息类型字段都支持字段存在性,如果已设置,它将出现在输出中。
Proto3 隐式存在性的标量字段仅在它们未设置为该类型的默认值时才会出现在 JSON 输出中。
Protobuf | JSON | JSON示例 | 说明 |
---|---|---|---|
message | object | {"fooBar": v, "g": null, ...} |
生成 JSON 对象。消息字段名称会被映射为小驼峰命名法(lowerCamelCase),并成为 JSON 对象的键。如果指定了 json_name 字段选项,则使用指定的值作为键。解析器接受小驼峰命名法的名称(或通过 json_name 选项指定的名称)以及原始的 proto 字段名称。null 是所有字段类型的有效值,并被视为相应字段类型的默认值。然而,null 不能用作 json_name 的值。有关原因,请参见 更严格的 json_name 验证。 |
enum | string | "FOO_BAR" |
使用 proto 中指定的枚举值名称。解析器同时接受枚举名称和整数值。 |
map<K,V> | object | {"k": v, ...} |
所有的键转换成strings |
repeated V | array | [v, ...] |
null 是合法的并会转换成空列表 [] |
bool | true,false | true,false |
|
string | string | "Hello World!" |
|
bytes | base64 string | "YWJjMTIzIT8kKiYoKSctPUB+" |
JSON 值将是使用标准 Base64 编码(带填充)编码的数据字符串。标准 Base64 编码或 URL 安全的 Base64 编码(带或不带填充)均可接受。 |
int32,fixed32,uint32 | number | 1, -10, 0 |
JSON 值将是一个十进制数字。接受数字或字符串类型。空字符串是无效的。 |
int64,fixed64,uint64 | string | "1", "-10" |
JSON 值将是一个十进制数字。接受数字或字符串类型。空字符串是无效的。 |
float,double | number | 1.1, -10.0, 0, "NaN", "Infinity" |
JSON 值将是一个数字或以下特殊字符串值之一:“NaN”、“Infinity” 和 “-Infinity”。接受数字或字符串类型。空字符串是无效的。也支持指数表示法。 |
Any | object |
{"@type": "url", "f": v, ... } |
如果 Any 包含具有特殊 JSON 映射的值,它将被转换如下:{"@type": xxx, "value": yyy} 。否则,值将被转换为 JSON 对象,并插入 "@type" 字段以指示实际的数据类型。 |
Timestamp | string | "1972-01-01T10:00:20.021Z" |
使用 RFC 3339,其中生成的输出将始终进行 Z 标准化,并使用 0, 3, 6 或 9 个小数位。接受除 "Z" 之外的其他偏移量。 |
Duration | string | "1.000340012s", "1s" |
生成的输出始终包含 0、3、6 或 9 个小数位,具体取决于所需的精度,后跟后缀 "s"。只要符合纳秒级精度要求,并且需要后缀 "s",则接受任何小数位(也可以没有小数位)。 |
Struct | object |
{ ... } |
任何 JSON 对象。查看 struct.proto |
Wrapper types | various types | 2, "2", "foo", true, "true", null, 0, ... |
包装器在 JSON 中使用与被包装的原始类型相同的表示方式,唯一不同的是在数据转换和传输过程中允许并保留 null 值。 |
FieldMask | string | "f.fooBar,h" |
查看 field_mask.proto |
ListValue | array | [foo, bar, ...] |
|
Value | value | 任何 JSON 值,详情请查看 google.protobuf.Value | |
NullValue | null | JSON null | |
Empty | object | {} |
空的JSON对象 |
符合规范的 protobuf JSON 实现可能提供以下选项:
optional
字段,但不影响 proto3 的 optional
字段。计划在未来的版本中修复此问题。