protobuf / json 数据转换(C++)

2020-10-28

protobuf 3.0 版本支持 protobuf 与 json 数据相互转换。


1. 转换接口

protobuf 与 json 数据转换接口在 google/protobuf/util/json_util.h 文件里。

1
2
3
4
5
/* protobuf 转 json。 */
inline util::Status MessageToJsonString(const Message& message, std::string* output);

/* json 换 protobuf。 */
inline util::Status JsonStringToMessage(StringPiece input, Message* message);

2. 测试源码

  • protobuf 结构。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
syntax = "proto3";
package kim;

message addr_info{
    string bind = 1;      /* bind host for inner server. */
    uint32 port = 2;      /* port for inner server. */
    string gate_bind = 3; /* bind host for user client. */
    uint32 gate_port = 4; /* port for user client. */
}

message node_info {
    string name = 1;         /* read from config and register to zk. */
    addr_info addr_info = 2; /* network addr info. */
    string node_type = 3;    /* node type in cluster. */
    string conf_path = 4;    /* config path. */
    string work_path = 5;    /* process work path. */
    int32 worker_cnt = 6;    /* number of worker's processes. */
}
  • 测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
#include <google/protobuf/util/json_util.h>
using google::protobuf::util::JsonStringToMessage;

void convert() {
    kim::node_info node;
    node.set_name("111111");
    node.mutable_addr_info()->set_bind("wruryeuwryeuwrw");
    node.mutable_addr_info()->set_port(342);
    node.mutable_addr_info()->set_gate_bind("fsduyruwerw");
    node.mutable_addr_info()->set_gate_port(4853);

    node.set_node_type("34rw343");
    node.set_conf_path("reuwyruiwe");
    node.set_work_path("ewiruwe");
    node.set_worker_cnt(3);

    std::string json_string;
    google::protobuf::util::JsonPrintOptions options;
    options.add_whitespace = true;
    options.always_print_primitive_fields = true;
    options.preserve_proto_field_names = true;
    MessageToJsonString(node, &json_string, options);

    std::cout << json_string << std::endl;

    node.Clear();
    if (JsonStringToMessage(json_string, &node).ok()) {
        std::cout << "json to protobuf: "
                  << node.name()
                  << ", "
                  << node.mutable_addr_info()->bind()
                  << std::endl;
    }
}

int main(int argc, char** argv) {
    convert();
    return 0;
}
  • 测试源码运行结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
 "name": "111111",
 "addr_info": {
  "bind": "wruryeuwryeuwrw",
  "port": 342,
  "gate_bind": "fsduyruwerw",
  "gate_port": 4853
 },
 "node_type": "34rw343",
 "conf_path": "reuwyruiwe",
 "work_path": "ewiruwe",
 "worker_cnt": 3
}

json to protobuf: 111111, wruryeuwryeuwrw

3. 参考