前言

项目上通过消息中间件传输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] = "{\"uri\":\"/uriCSh56j30cbGa\",\"host\":\"www.baidu.com\",\"uagent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"resp_content_type\":\"video/fli\",\"status\":200,\"resp_content_length\":20480,\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"traffic_id\":1057153235624398,\"protocol\":\"http\",\"src_ip\":\"112.1.101.40\",\"src_port\":22291,\"dst_ip\":\"112.2.81.190\",\"dst_port\":80,\"random_code\":7449212903698783717,\"feature_code\":\"y0BMEwnJ7RFICUAC5FKYkStTLVw=\"}";
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, "src_port");
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] = "{\"uri\":\"/uriCSh56j30cbGa\",\"host\":\"www.baidu.com\",\"uagent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"resp_content_type\":\"video/fli\",\"status\":200,\"resp_content_length\":20480,\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"traffic_id\":1057153235624398,\"protocol\":\"http\",\"src_ip\":\"112.1.101.40\",\"src_port\":22291,\"dst_ip\":\"112.2.81.190\",\"dst_port\":80,\"random_code\":7449212903698783717,\"feature_code\":\"y0BMEwnJ7RFICUAC5FKYkStTLVw=\"}";
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 // 确定有src_port,直接取值
22 cout << "src_port:" << parse_doc.FindMember("src_port")->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] = "{\"uri\":\"/uriCSh56j30cbGa\",\"host\":\"www.baidu.com\",\"uagent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124\",\"accept\":\"*/*\",\"method\":\"GET\",\"date\":\"Mon, 12 Jul 21 10:35:26 GMT\",\"resp_content_type\":\"video/fli\",\"status\":200,\"resp_content_length\":20480,\"timestamp\":\"2021-07-12T02:38:13.074829000\",\"traffic_id\":1057153235624398,\"protocol\":\"http\",\"src_ip\":\"112.1.101.40\",\"src_port\":22291,\"dst_ip\":\"112.2.81.190\",\"dst_port\":80,\"random_code\":7449212903698783717,\"feature_code\":\"y0BMEwnJ7RFICUAC5FKYkStTLVw=\"}";
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 // 确定有src_port,直接取值
25 cout << "src_port:" << yyjson_get_int(yyjson_obj_get(root, "src_port")) << 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解析工具都可以完成基础的数据解析,看似没有区别,好像可以任选一种。

但是,如果对数据解析的正确性,高效性有要求,就需要做相关取舍了,具体分析请看后续文章。

json系列(一)cjson,rapidjson,yyjson解析示例的更多相关文章

  1. json系列(三)cjson,rapidjson,yyjson解析性能对比

    前言 本篇对cjson,rapidjson,yyjson三种json反序列化工具的性能进行对比. 有json样本数据如下: 实验环境: cpu:Xeon cpu主频:2.20GHz 以下示例均未对字段 ...

  2. json系列(二)cjson,rapidjson,yyjson大整数解析精度对比

    前言上一篇介绍了3种json解析工具的使用方法,对于基础数据的解析没有任何问题.我们传输的json数据里有unsigned long型数据,需要借助json解析工具得到正确的unsigned long ...

  3. rapidjson常见使用示例

    目录 目录 1 1. 前言 2 2. Move语意 2 3. rapidjson::Document 2 4. 成员迭代器MemberIterator 3 5. 数组迭代器ValueIterator ...

  4. 【转】 cJSON 源码解析

    关于cjson的介绍和使用方法就不在这里介绍了,详情请查看上一篇博客cjson使用方法. JSON的内存结构像广义表,可以认为是有层次的双向链表. cJSON程序中的细节点如下: 大量宏替换 大量静态 ...

  5. 【Flask-RESTPlus系列】Part3:请求解析

    0x00 内容概览 请求解析 基本参数 必需参数 多值和列表 其他目标 参数位置 参数多个位置 高级类型处理 解析器继承 文件上传 错误处理 错误消息 参考链接 0x01 请求解析 注意:Flask- ...

  6. Mybatis 系列8-结合源码解析select、resultMap的用法

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  7. Mybatis 系列7-结合源码解析核心CRUD 配置及用法

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  8. Mybatis 系列3-结合源码解析properties节点和environments节点

    [Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...

  9. asp.net core系列 39 Razor 介绍与详细示例

    原文:asp.net core系列 39 Razor 介绍与详细示例 一. Razor介绍 在使用ASP.NET Core Web开发时, ASP.NET Core MVC 提供了一个新特性Razor ...

随机推荐

  1. C++构造函数语义学(三)(基于C++对象模型)

    带有虚基类的情况. 1 #include<iostream> 2 using namespace std; 3 class X 4 { 5 public: 6 int i; 7 }; 8 ...

  2. golang中goroutine

    1. 概念 goroutine 奉行通过通信来共享内存,而不是共享内存来通信 goroutine 是由go的运行时(runtime)调度和管理的 go程序会智能的将goroutine中的任务合理的分配 ...

  3. golang中的udp编程

    1. udp server package main import ( "fmt" "net" ) func main() { // udp server li ...

  4. String类(获取,转换,判断,比较)

    1 package cn.itcast.p1.string.demo; 2 3 import java.util.Iterator; 4 5 import com.sun.org.apache.xpa ...

  5. 前端禁止使用F12、禁止右键

    打开控制台直接跳转页面 //debug调试时跳转页面 var element = new Image(); Object.defineProperty(element,'id',{get:functi ...

  6. MySQL技术内幕(一)

    MySQL技术内幕 2. InnoDB存储引擎 2.1 InnoDB存储引擎概述 特点:行锁设计.支持MVCC.支持外键.提供一致性非锁定读 2.2 InnoDB体系架构 2.2.1 后台线程 Inn ...

  7. 负载均衡后端状态(proxy_next_upstream 后端错误标识)

    目录 一:负载均衡后端状态 二:down(无论什么情况不会分配流量) 三:backup(备用只有当所有的机器宕机(关闭)才能启动备份服务器) 四:max_fails.fail_timeout(结合使用 ...

  8. Python中的魔术方法

    什么是魔术方法? 在Python中,所有用"__"包起来的方法,都称为[魔术方法]. 魔术方法一般是为了让显示器调用的,你自己并不需要调用它们. __init__:初始化函数 这个 ...

  9. MySQL 行锁、表锁

    1. 多个事务操作同一行数据时,后来的事务处于阻塞等待状态.这样可以避免了脏读等数据一致性的问题.后来的事务可以操作其他行数据,解决了表锁高并发性能低的问题 2.InnoDB的行锁是针对索引加的锁,不 ...

  10. Linux命令date日期时间和Unix时间戳互转

    A.将日期转换为Unix时间戳将当前时间以Unix时间戳表示: date +%s 输出如下: 1361542433 转换指定日期为Unix时间戳: date -d '2013-2-22 22:14' ...