素材巴巴 > 程序开发 >

数据序列化:Json简介及使用

程序开发 2023-09-08 13:40:57

文章目录

  • 四、数据反序列化实例
  • 一、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++库的一个简单使用了,如有错误还望批评指正。


    标签:

    上一篇: 【跨域】Java后端解决跨域问题 下一篇:
    素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。