rapidjson库的基本使用
转自:https://blog.csdn.net/qq849635649/article/details/52678822
我在工作中一直使用的是rapidjson库,这是我在工作中使用该库作的一些整理,以读写下面的这段json字符串为例来进行整理,该字符串覆盖了平时使用的布尔类型、整型、浮点类型、结构体类型、字符串类型以及相对应的数组类型。
代码地址:https://git.oschina.net/zhaoyf/zhaoyf_csdn/tree/master/test_json
这时生成的目标json字符串
{ "Int": 1, "Double": 12.0000001, "String": "This is a string", "Object": { "name": "qq849635649", "age": 25 }, "IntArray": [ 10, 20, 30 ], "DoubleArray": [ 1, 2, 3 ], "StringArray": [ "one", "two", "three" ], "MixedArray": [ "one", 50, false, 12.005 ], "People": [ { "name": "qq849635649", "age": 0, "sex": true }, { "name": "qq849635649", "age": 10, "sex": false }, { "name": "qq849635649", "age": 20, "sex": true } ] }
一、写json协议
1. 下面这段代码是我最喜欢用的一种方式,使用字符串缓冲器生成
1 #include "rapidjson/stringbuffer.h" 2 #include "rapidjson/writer.h" 3 #include <iostream> 4 #include <string> 5 6 using namespace std; 7 8 void Serialize_1() 9 { 10 rapidjson::StringBuffer strBuf; 11 rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf); 12 13 writer.StartObject(); 14 15 //1. 整数类型 16 writer.Key("Int"); 17 writer.Int(1); 18 19 //2. 浮点类型 20 writer.Key("Double"); 21 writer.Double(12.0000001); 22 23 //3. 字符串类型 24 writer.Key("String"); 25 writer.String("This is a string"); 26 27 //4. 结构体类型 28 writer.Key("Object"); 29 writer.StartObject(); 30 writer.Key("name"); 31 writer.String("qq849635649"); 32 writer.Key("age"); 33 writer.Int(25); 34 writer.EndObject(); 35 36 //5. 数组类型 37 //5.1 整型数组 38 writer.Key("IntArray"); 39 writer.StartArray(); 40 //顺序写入即可 41 writer.Int(10); 42 writer.Int(20); 43 writer.Int(30); 44 writer.EndArray(); 45 46 //5.2 浮点型数组 47 writer.Key("DoubleArray"); 48 writer.StartArray(); 49 for(int i = 1; i < 4; i++) 50 { 51 writer.Double(i * 1.0); 52 } 53 writer.EndArray(); 54 55 //5.3 字符串数组 56 writer.Key("StringArray"); 57 writer.StartArray(); 58 writer.String("one"); 59 writer.String("two"); 60 writer.String("three"); 61 writer.EndArray(); 62 63 //5.4 混合型数组 64 //这说明了,一个json数组内容是不限制类型的 65 writer.Key("MixedArray"); 66 writer.StartArray(); 67 writer.String("one"); 68 writer.Int(50); 69 writer.Bool(false); 70 writer.Double(12.005); 71 writer.EndArray(); 72 73 //5.5 结构体数组 74 writer.Key("People"); 75 writer.StartArray(); 76 for(int i = 0; i < 3; i++) 77 { 78 writer.StartObject(); 79 writer.Key("name"); 80 writer.String("qq849635649"); 81 writer.Key("age"); 82 writer.Int(i * 10); 83 writer.Key("sex"); 84 writer.Bool((i % 2) == 0); 85 writer.EndObject(); 86 } 87 writer.EndArray(); 88 89 writer.EndObject(); 90 91 string data = strBuf.GetString(); 92 cout << data << endl; 93 }
2. 接下来这种方式是我刚开始学习使用该库时网上收到的结果,使用不像上面那么方便
1 #include "rapidjson/document.h" 2 #include "rapidjson/stringbuffer.h" 3 #include "rapidjson/writer.h" 4 5 6 void Serialize_2() 7 { 8 rapidjson::Document doc; 9 doc.SetObject(); 10 rapidjson::Document::AllocatorType& allocator = doc.GetAllocator(); 11 12 //1. 整型类型 13 doc.AddMember("Int", 1, allocator); 14 15 //2. 浮点类型 16 doc.AddMember("Double", 12.00001, allocator); 17 18 //3. 字符串类型 19 //正确方式 20 string str= "This is a string"; 21 rapidjson::Value str_value(rapidjson::kStringType); 22 str_value.SetString(str.c_str(), str.size()); 23 if(!str_value.IsNull()) 24 { 25 doc.AddMember("String", str_value, allocator); 26 } 27 /** 28 * 注:以下方式不正确,可能成功,也可能失败,因为字符串写入json要重新开辟内存, 29 * 如果使用该方式的话,当数据是字符串常量的话是没问题的,如果为变量就会显示乱码,所 30 * 以为保险起见,我们显式的分配内存(无需释放) 31 */ 32 //doc.AddMember("String", str.data(), allocator); 33 34 //4. 结构体类型 35 rapidjson::Value object(rapidjson::kObjectType); 36 object.AddMember("name", "qq849635649", allocator); //注:常量是没有问题的 37 object.AddMember("age", 25, allocator); 38 doc.AddMember("Object", object, allocator); 39 40 //5. 数组类型 41 //5.1 整型数组 42 rapidjson::Value IntArray(rapidjson::kArrayType); 43 IntArray.PushBack(10, allocator); 44 IntArray.PushBack(20, allocator); 45 IntArray.PushBack(30, allocator); 46 doc.AddMember("IntArray", IntArray, allocator); 47 48 //5.2 浮点型数组 49 rapidjson::Value DoubleArray(rapidjson::kArrayType); 50 DoubleArray.PushBack(1.0, allocator); 51 DoubleArray.PushBack(2.0, allocator); 52 DoubleArray.PushBack(3.0, allocator); 53 doc.AddMember("DoubleArray", DoubleArray, allocator); 54 55 //5.3 字符型数组 56 rapidjson::Value StringArray(rapidjson::kArrayType); 57 string strValue1 = "one"; 58 string strValue2 = "two"; 59 string strValue3 = "three"; 60 str_value.SetString(strValue1.c_str(), strValue1.size()); 61 StringArray.PushBack(str_value, allocator); 62 str_value.SetString(strValue2.c_str(), strValue2.size()); 63 StringArray.PushBack(str_value, allocator); 64 str_value.SetString(strValue3.c_str(), strValue3.size()); 65 StringArray.PushBack(str_value, allocator); 66 doc.AddMember("StringArray", StringArray, allocator); 67 68 //5.4 结构体数组 69 rapidjson::Value ObjectArray(rapidjson::kArrayType); 70 for(int i = 1; i < 4; i++) 71 { 72 rapidjson::Value obj(rapidjson::kObjectType); 73 obj.AddMember("name", "qq849635649", allocator);//注:常量是没有问题的 74 obj.AddMember("age", i * 10, allocator); 75 ObjectArray.PushBack(obj, allocator); 76 } 77 doc.AddMember("ObjectArray", ObjectArray, allocator); 78 79 rapidjson::StringBuffer strBuf; 80 rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf); 81 doc.Accept(writer); 82 83 string data = strBuf.GetString(); 84 cout << data << endl; 85 }
下面是解析的代码,同样的,采用的依旧上面那个json字符串,分门别类的已经整理好
1 #include "rapidjson/document.h" 2 #include "rapidjson/stringbuffer.h" 3 #include "rapidjson/writer.h" 4 5 string data = 6 "{\"Int\":1," 7 "\"Double\":12.0000001," 8 "\"String\":\"This is a string\"," 9 "\"Object\":{\"name\":\"qq849635649\",\"age\":25}," 10 "\"IntArray\":[10,20,30]," 11 "\"DoubleArray\":[1.0,2.0,3.0]," 12 "\"StringArray\":[\"one\",\"two\",\"three\"]," 13 "\"MixedArray\":[\"one\",50,false,12.005]," 14 "\"People\":[{\"name\":\"qq849635649\",\"age\":0,\"sex\":true}," 15 "{\"name\":\"qq849635649\",\"age\":10,\"sex\":false}," 16 "{\"name\":\"qq849635649\",\"age\":20,\"sex\":true}]}"; 17 18 void parse() { 19 //创建解析对象 20 rapidjson::Document doc; 21 //首先进行解析,没有解析错误才能进行具体字段的解析 22 if(!doc.Parse(data.data()).HasParseError()) 23 { 24 //1. 解析整数 25 if(doc.HasMember("Int") && doc["Int"].IsInt()) 26 { 27 cout << "Int = " << doc["Int"].GetInt() << endl; 28 } 29 //2. 解析浮点型 30 if(doc.HasMember("Double") && doc["Double"].IsDouble()) 31 { 32 cout << "Double = " << doc["Double"].GetDouble() << endl; 33 } 34 //3. 解析字符串 35 if(doc.HasMember("String") && doc["String"].IsString()) 36 { 37 cout << "String = " << doc["String"].GetString() << endl; 38 } 39 //4. 解析结构体 40 if(doc.HasMember("Object") && doc["Object"].IsObject()) 41 { 42 const rapidjson::Value& object = doc["Object"]; 43 if(object.HasMember("name") && object["name"].IsString()) 44 { 45 cout << "Object.name = " << object["name"].GetString() << endl; 46 } 47 if(object.HasMember("age") && object["age"].IsInt()) 48 { 49 cout << "Object.age = " << object["age"].GetInt() << endl; 50 } 51 } 52 //5. 解析数组类型 53 //5.1 整型数组类型 54 if(doc.HasMember("IntArray") && doc["IntArray"].IsArray()) 55 { 56 //5.1.1 将字段转换成为rapidjson::Value类型 57 const rapidjson::Value& array = doc["IntArray"]; 58 //5.1.2 获取数组长度 59 size_t len = array.Size(); 60 //5.1.3 根据下标遍历,注意将元素转换为相应类型,即需要调用GetInt() 61 for(size_t i = 0; i < len; i++) 62 { 63 cout << "IntArray[" << i << "] = " << array[i].GetInt() << endl; 64 } 65 } 66 //5.2 浮点型数组类型 67 if(doc.HasMember("DoubleArray") && doc["DoubleArray"].IsArray()) 68 { 69 const rapidjson::Value& array = doc["DoubleArray"]; 70 size_t len = array.Size(); 71 for(size_t i = 0; i < len; i++) 72 { 73 //为防止类型不匹配,一般会添加类型校验 74 if(array[i].IsDouble()) 75 { 76 cout << "DoubleArray[" << i << "] = " << array[i].GetDouble() << endl; 77 } 78 } 79 } 80 //5.3 字符串数组类型 81 if(doc.HasMember("StringArray") && doc["StringArray"].IsArray()) 82 { 83 const rapidjson::Value& array = doc["StringArray"]; 84 size_t len = array.Size(); 85 for(size_t i = 0; i < len; i++) 86 { 87 //为防止类型不匹配,一般会添加类型校验 88 if(array[i].IsString()) 89 { 90 cout << "StringArray[" << i << "] = " << array[i].GetString() << endl; 91 } 92 } 93 } 94 //5.4 混合型 95 if(doc.HasMember("MixedArray") && doc["MixedArray"].IsArray()) 96 { 97 const rapidjson::Value& array = doc["MixedArray"]; 98 size_t len = array.Size(); 99 for(size_t i = 0; i < len; i++) 100 { 101 //为防止类型不匹配,一般会添加类型校验 102 if(array[i].IsString()) 103 { 104 cout << "MixedArray[" << i << "] = " << array[i].GetString() << endl; 105 } 106 else if(array[i].IsBool()) 107 { 108 cout << "MixedArray[" << i << "] = " << array[i].GetBool() << endl; 109 } 110 else if(array[i].IsInt()) 111 { 112 cout << "MixedArray[" << i << "] = " << array[i].GetInt() << endl; 113 } 114 else if(array[i].IsDouble()) 115 { 116 cout << "MixedArray[" << i << "] = " << array[i].GetDouble() << endl; 117 } 118 } 119 } 120 //5.5 结构体数组类型 121 if(doc.HasMember("People") && doc["People"].IsArray()) 122 { 123 const rapidjson::Value& array = doc["People"]; 124 size_t len = array.Size(); 125 for(size_t i = 0; i < len; i++) 126 { 127 const rapidjson::Value& object = array[i]; 128 //为防止类型不匹配,一般会添加类型校验 129 if(object.IsObject()) 130 { 131 cout << "ObjectArray[" << i << "]: "; 132 if(object.HasMember("name") && object["name"].IsString()) 133 { 134 cout << "name=" << object["name"].GetString(); 135 } 136 if(object.HasMember("age") && object["age"].IsInt()) 137 { 138 cout << ", age=" << object["age"].GetInt(); 139 } 140 if(object.HasMember("sex") && object["sex"].IsBool()) 141 { 142 cout << ", sex=" << (object["sex"].GetBool() ? "男" : "女") << endl; 143 } 144 } 145 } 146 } 147 } 148 /** 149 * 最后注意:因为rapidjson不会做安全校验,所以要自己做安全校验,以int整型为例 150 * “if(object.HasMember("age") && object["age"].IsInt()) {}” 151 * 这句校验很重要,既要校验有该子段,也要校验类型正确,否则会引发程序崩溃 152 */ 153 }
所有的代码都放在上面了,我想不用解释太多,代码浅显易懂,不懂的话可以回复评论。