前言
項目上通過消息中間件傳輸json格式的數據,其他接收模塊需要對json格式的數據進行解析,反序列化。
對json解析工具有幾個關注點,一是具備解析和構造的基礎功能,二是具備解析和構造的高性能,三是解析和構造的正確性。
本篇簡單介紹三種json解析工具的使用方法,解析構造的正確性和性能對比在接下來的文章里介紹。
有json樣本數據如下:
一、cjson解析示例
1 #include "cJSON.h" 2 3 #include <iostream> 4 5 // g++ -g -o cjson_parse_test -std=c++11 cjson_parse.c cJSON.c 6 7 using namespace std; 8 9 int main() 10 { 11 cJSON *json_tmp; 12 cJSON *json_root; 13 14 char str_buf[1024] = "{\"host\":\"www.baidu.com\",\"hostlen\":13,\"uagent\":\"curl/7.29.0\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"protocol_type\":\"http\",\"source_ip\":\"::112.1.101.40\",\"source_port\":22291,\"destination_ip\":\"::112.2.81.190\",\"destination_port\":80,\"flow_timestamp\":\"2021-07-12 02:38:13.074829000\",\"flow_id\":6996903014416199548,\"key_id\":7449212903698783717,\"token\":\"1556198765_129_1_8BFE1790A603B9C0067938B07CB5BB94B6926B81\"}"; 15 16 json_root = cJSON_Parse(str_buf); 17 18 json_tmp = cJSON_GetObjectItem(json_root, "host"); 19 if(NULL != json_tmp) { 20 cout << "host:" << json_tmp->valuestring << endl; 21 } 22 23 json_tmp = cJSON_GetObjectItem(json_root, "hostlen"); 24 if(NULL != json_tmp) { 25 cout << "hostlen:" << json_tmp->valueint << endl; 26 } 27 28 json_tmp = cJSON_GetObjectItem(json_root, "uagent"); 29 if(NULL != json_tmp) { 30 cout << "uagent:" << json_tmp->valuestring << endl; 31 } 32 33 json_tmp = cJSON_GetObjectItem(json_root, "accept"); 34 if(NULL != json_tmp) { 35 cout << "accept:" << json_tmp->valuestring << endl; 36 } 37 38 cJSON_Delete(json_root); 39 return 0; 40 }
執行結果:
二、rapidjson解析示例
1 #include <iostream> 2 3 #include "rapidjson/document.h" 4 #include "rapidjson/rapidjson.h" 5 6 // g++ -g -o rapidjson_parse_test -std=c++11 rapidjson_parse.c 7 8 using namespace std; 9 10 int main() 11 { 12 char str_buf[1024] = "{\"host\":\"www.baidu.com\",\"hostlen\":13,\"uagent\":\"curl/7.29.0\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"protocol_type\":\"http\",\"source_ip\":\"::112.1.101.40\",\"source_port\":22291,\"destination_ip\":\"::112.2.81.190\",\"destination_port\":80,\"flow_timestamp\":\"2021-07-12 02:38:13.074829000\",\"flow_id\":6996903014416199548,\"key_id\":7449212903698783717,\"token\":\"1556198765_129_1_8BFE1790A603B9C0067938B07CB5BB94B6926B81\"}"; 13 14 rapidjson::Document parse_doc; 15 16 parse_doc.Parse(str_buf); 17 18 // 確定有host,直接取值 19 cout << "host:" << parse_doc.FindMember("host")->value.GetString() << endl; 20 21 // 確定有hostlen,直接取值 22 cout << "hostlen:" << parse_doc.FindMember("hostlen")->value.GetInt() << endl; 23 24 // 不確定是否有uagent,先判斷 25 if(parse_doc.HasMember("uagent")) { 26 cout << "uagent:" << parse_doc.FindMember("uagent")->value.GetString() << endl; 27 } 28 29 // 不確定是否有accept,先判斷。 30 // 通過parse_doc["accept"]形式取值,但是這種方法取值性能沒有FindMember高 31 if(parse_doc.HasMember("accept")) { 32 cout << "accept:" << parse_doc["accept"].GetString() << endl; 33 } 34 35 return 0; 36 }
執行結果:
三、yyjson解析示例
1 #include <iostream> 2 3 #include "yyjson.h" 4 5 // g++ -g -o yyjson_parse_test -std=c++11 yyjson_parse.c yyjson.c 6 7 using namespace std; 8 9 int main() 10 { 11 char str_buf[1024] = "{\"host\":\"www.baidu.com\",\"hostlen\":13,\"uagent\":\"curl/7.29.0\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"protocol_type\":\"http\",\"source_ip\":\"::112.1.101.40\",\"source_port\":22291,\"destination_ip\":\"::112.2.81.190\",\"destination_port\":80,\"flow_timestamp\":\"2021-07-12 02:38:13.074829000\",\"flow_id\":6996903014416199548,\"key_id\":7449212903698783717,\"token\":\"1556198765_129_1_8BFE1790A603B9C0067938B07CB5BB94B6926B81\"}"; 12 13 yyjson_val *key; 14 15 yyjson_doc *doc; 16 yyjson_val *root; 17 18 doc = yyjson_read(str_buf, strlen(str_buf), 0); 19 root = yyjson_doc_get_root(doc); 20 21 // 確定有host,直接取值 22 cout << "host:" << yyjson_get_str(yyjson_obj_get(root, "host")) << endl; 23 24 // 確定有hostlen,直接取值 25 cout << "hostlen:" << yyjson_get_int(yyjson_obj_get(root, "hostlen")) << endl; 26 27 // 不確定是否有uagent,先判斷 28 if(NULL != (key = yyjson_obj_get(root, "uagent"))) { 29 cout << "uagent:" << yyjson_get_str(key) << endl; 30 } 31 32 // 不確定是否有accept,先判斷 33 if(NULL != (key = yyjson_obj_get(root, "accept"))) { 34 cout << "accept:" << yyjson_get_str(key) << endl; 35 } 36 37 yyjson_doc_free(doc); 38 return 0; 39 }
執行結果:
結論
三種json解析工具都可以完成基礎的數據解析,看似沒有區別,好像可以任選一種。
但是,如果對數據解析的正確性,高效性有要求,就需要做相關取舍了,具體分析請看后續文章。