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 文件(nodes.proto)。
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. */
}
- 执行脚本将 proto 文件生成 C++ protobuf 代码。
1
protoc -I. *.proto --cpp_out=.
- 测试代码(test_proto_json.cpp)。
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <google/protobuf/util/json_util.h>
#include <iostream>
#include "nodes.pb.h"
using google::protobuf::util::JsonStringToMessage;
bool proto_to_json(const google::protobuf::Message& message, std::string& json) {
google::protobuf::util::JsonPrintOptions options;
options.add_whitespace = true;
options.always_print_primitive_fields = true;
options.preserve_proto_field_names = true;
return MessageToJsonString(message, &json, options).ok();
}
bool json_to_proto(const std::string& json, google::protobuf::Message& message) {
return JsonStringToMessage(json, &message).ok();
}
int main() {
kim::node_info node;
std::string json_string;
node.set_name("111111");
node.set_node_type("34rw343");
node.set_conf_path("reuwyruiwe");
node.set_work_path("ewiruwe");
node.set_worker_cnt(3);
node.mutable_addr_info()->set_bind("xxxxxxxxxx");
node.mutable_addr_info()->set_port(342);
node.mutable_addr_info()->set_gate_bind("fsduyruwerw");
node.mutable_addr_info()->set_gate_port(4853);
/* protobuf 转 json。 */
if (!proto_to_json(node, json_string)) {
std::cout << "protobuf convert json failed!" << std::endl;
return 1;
}
std::cout << "protobuf convert json done!" << std::endl
<< json_string << std::endl;
node.Clear();
std::cout << "-----" << std::endl;
/* json 转 protobuf。 */
if (!json_to_proto(json_string, node)) {
std::cout << "json to protobuf failed!" << std::endl;
return 1;
}
std::cout << "json to protobuf done!" << std::endl
<< "name: " << node.name() << std::endl
<< "bind: " << node.mutable_addr_info()->bind()
<< std::endl;
return 0;
}
- 编译运行。
1
g++ -std='c++11' nodes.pb.cc test_proto_json.cpp -lprotobuf -lpthread -o pj && ./pj
- 程序运行结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
protobuf convert json done!
{
"name": "111111",
"addr_info": {
"bind": "xxxxxxxxxx",
"port": 342,
"gate_bind": "fsduyruwerw",
"gate_port": 4853
},
"node_type": "34rw343",
"conf_path": "reuwyruiwe",
"work_path": "ewiruwe",
"worker_cnt": 3
}
-----
json to protobuf done!
name: 111111
bind: xxxxxxxxxx