文章目录

一、Json简介二、Json语法三、数据序列化实例3.1 普通数据序列化3.2 容器序列化

四、数据反序列化实例4.1 普通数据反序列化4.2 容器反序列化

一、Json简介

Json(JavaScript Object Notation):是一种轻量级的数据交换格式(也叫数据序列化方式),采用完全独立于编程语言的文本格式来存储和表示数据。 简洁和清晰的层次结构使得 Json 成为理想的数据交换语言,易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。 例如:聊天软件的业务,消息种类分为很多种,例如:登录消息、注册消息、聊天消息、加好友消息等等,需要进行具体消息种类的区分,还需要知道消息从谁来,要到哪去,以及消息内容是什么等字段。而网络中TCP传输数据时为字节流,因此我们需要数据序列化将其转为字节流发送到对端主机,对端主机读取字节流上报应用服务,再将数据反序列化出来解析使用。

优秀的Json开源库JSON for Modern C++:由德国大牛 nlohmann 编写的在 C++ 下使用的 Json 库,具有以下优点: 1、直观的语法; 2、整个代码由一个头文件组成 json.hpp,没有子项目、、依赖关系、复杂的构建系统,使用起来非常方便; 3、使用 C++ 11 标准编写,使用 Json 像使用 STL 容器一样; 4、STL 和 Json 容器之间可以相互转换; 5、所有类都经过严格的单元测试,覆盖了 100% 的代码,包括所有特殊的行为。此外,还检查了 Valgrind 是否有内存泄漏。为了保持高质量,该项目遵循核心基础设施倡议(CII)的最佳实践。  

二、Json语法

Json语法:它是JavaScript 对象表示语法的子集,主要有以下特点: 1、数据在名称/值对中; 2、数据由逗号 , 分隔; 3、使用斜杆 \ 来转义字符; 4、大括号 {} 保存对象; 5、中括号 [] 保存数组,数组可以包含多个对象;

Json的两种结构: 1、对象: 大括号 {} 保存的对象是一个无序的名称/值对集合。一个对象以左括号 { 开始, 右括号 } 结束。每个"键"后跟一个冒号 :,名称/值对使用逗号 , 分隔。 2、数组: 中括号 [] 保存的数组是值(value)的有序集合。一个数组以左中括号[开始, 右中括号 ]结束,值之间使用逗号 , 分隔。值(value)可以是双引号括起来的字符串、数值、true、false、 null、对象或者数组,也可以是他们的嵌套类型。

书写格式: key : value格式,类似于我们C++中的map容器,十分简洁清晰,例如:

json js;

js["name"] = "xiaoming";

 

三、数据序列化实例

Json序列化: 在网络中,常用的数据传输序列化格式有XML、Json、ProtoBuf,在公司级别的项目中,大量的在使用ProtoBuf作为数据序列化的方式,它数据压缩编码传输,占用带宽小,同样的数据信息,是Json的1/10,XML的1/20,但是使用起来比Json稍复杂一些,学习成本较高,所以项目中我们选择常用的Json格式来打包传输数据。

使用前准备:需要提前下载好Json.hpp,使用时引入头文件即可。

#include "json.hpp"

using json = nlohmann::json;

 

3.1 普通数据序列化

1、Json进行普通数据序列化:

//1、Json普通数据序列化

void test1()

{

json js; //添加Json对象

js["msg_type"] = 2;

js["from"] = "zhangsan";

js["to"] = "lisi";

js["msg"] = "hello, good morning!";

cout << js << endl;

}

序列化输出Json字符串:   2、Json序列化:利用dump()方法,将dict类型的数据转成str。

//1、Json普通数据序列化

void test1()

{

json js; //添加Json对象

js["msg_type"] = 2;

js["from"] = "zhangsan";

js["to"] = "lisi";

js["msg"] = "hello, good morning!";

string sendBuf = js.dump(); //Json数据对象 =》 Json字符串

cout << sendBuf.c_str() << endl;

}

输出string字符串,可以在网络中进行传输:   3、Json添加数组类型:

//2、Json添加数组类型

void test2()

{

json js;

js["id"] = {1, 2, 3, 4, 5}; //添加数组

js["name"] = "zhangsan"; //添加key-value

js["msg"]["zhangsan"] = "good noon!";

js["msg"]["lisi"] = "good night!";

js["msg"] = {{"zhangsan", "good noon!"}, {"lisi", "good night!"}}; //添加Json对象,上面两句等同于此句一次性添加数组对象

cout << js << endl;

}

序列化结果如下,输出结果一致的:  

3.2 容器序列化

1、容器序列化:

//3、容器序列化

void test3()

{

json js;

//3.1 直接序列化一个vector容器

vector vec;

vec.push_back(1);

vec.push_back(2);

vec.push_back(3);

js["list"] = vec;

//3.2 直接序列化一个map容器

map m;

m.insert({1, "黄山"});

m.insert({2, "华山"});

m.insert({3, "泰山"});

js["local"] = m;

cout << js << endl;

}

序列化结果如下:  

四、数据反序列化实例

Json反序列化: 当我们从网络接收到字符串为Json格式时,可以用JSON for Modern C++ 直接反序列化取得数据或者直接反序列化出对象,甚至是容器。

4.1 普通数据反序列化

1、Json普通数据反序列化:利用parse()方法,从Json字符串反序列化为Json数据对象,类似于容器方便访问。

//4、Json普通数据反序列化

string test4()

{

json js; //添加Json对象

js["msg_type"] = 2;

js["from"] = "zhangsan";

js["to"] = "lisi";

js["msg"] = "hello, good morning!";

string sendBuf = js.dump(); //Json数据对象 =》 Json字符串

return sendBuf;

}

int main()

{

string recvBuf = test4();

json jsbuf = json::parse(recvBuf); //反序列化,Json字符串 => 数据对象

cout << jsbuf["msg_type"] << endl;

cout << jsbuf["from"] << endl;

cout << jsbuf["to"] << endl;

cout << jsbuf["msg"] << endl;

return 0;

}

反序列化输出结果如下,还保留了相应数据类型。

2、其它类型数据反序列化:

//5、Json其它类型数据反序列化

string test5()

{

json js;

js["id"] = {1, 2, 3, 4, 5}; //添加数组

js["name"] = "zhangsan"; //添加key-value

js["msg"]["zhangsan"] = "good noon!";

js["msg"]["lisi"] = "good night!";

js["msg"] = {{"zhangsan", "good noon!"}, {"lisi", "good night!"}}; //添加Json对象,上面两句等同于此句一次性添加数组对象

return js.dump();

}

int main()

{

string recvBuf = test5();

json jsbuf = json::parse(recvBuf);

cout << jsbuf["id"] << endl;

auto jsmsg = jsbuf["msg"];

cout << jsmsg["zhangsan"] << endl;

cout << jsmsg["lisi"] << endl;

return 0;

}

反序列化结果如下:  

4.2 容器反序列化

1、容器反序列化:

//6、容器反序列化

string test6()

{

json js;

//6.1 直接序列化一个vector容器

vector vec;

vec.push_back(1);

vec.push_back(2);

vec.push_back(3);

js["list"] = vec;

//6.2 直接序列化一个map容器

map m;

m.insert({1, "黄山"});

m.insert({2, "华山"});

m.insert({3, "泰山"});

js["local"] = m;

string sendbuf = js.dump();

return sendbuf;

}

int main()

{

string recvBuf = test6();

json jsbuf = json::parse(recvBuf);

vector vec = jsbuf["list"]; //将js对象中数组类型直接放入vector容器中

for (int v : vec)

{

cout << v << " ";

}

cout << endl;

map mp = jsbuf["local"]; //将js对象中数组类型直接放入map容器中

for (auto it : mp)

{

cout << it.first << " " << it.second << endl;

}

cout << endl;

return 0;

}

反序列化结果如下: 以上就是我们基于用JSON for Modern C++库的一个简单使用了,如有错误还望批评指正。

文章来源

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: