-
Author:Echo Chen(箱子)
-
Email:chenb19870707@gmail.com
-
Date:September 28th, 2014
Explain
近期在做游戲接入SDK時用到C++的json庫jsoncpp。jsoncpp 是一款優秀的json庫。但惡心的一點是它採用Assert作為錯誤處理方法,而assert在linux下通過調用 abort 來終止程序執行,對於server而言將會收到SIGABRT,崩潰打出core,這對於server而言是致命的,以下總結了幾種 Assertion `type_ == nullValue || type_ == object Value' failed的情況。
1. json字符串不合法
1: Json::Reader *pJsonParser = new Json::Reader();
2: string strJson = "1111 {}"; //不合法json
3:
4: Json::Value tempVal;
5:
6: if(!pJsonParser->parse(strJson, tempVal))
7: {
8: cout << "parse error" << endl;
9: return -1;
10: }
11: string name = tempVal["name"].asString();
因為Jsoncpp解析非法json時。會自己主動容錯成字符類型。對字符類型取下標時,會觸發assert終止進程。
解決方法:啟用嚴格模式,讓非法的json解析時直接返回false,不自己主動容錯。這樣。在調用parse的時候就會返回false。
1: Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
2.解析串為json數組
1: Json::Reader *pJsonParser = new Json::Reader();
2: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\',\'sex\':\'男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";
3:
4: Json::Value tempVal;
5:
6: if(!pJsonParser->parse(strJson, tempVal))
7: {
8: return -1;
9: }
10:
11: string friendsName = tempVal["friends"]["name"].asString();
因為friends為數組,直接取name,會Assertion `type_ == nullValue || type_ == objectValue' failed.
解決方法:循環讀取數組
1: Json::Value friends = tempVal["friends"];
2: for(int i = 0;i < friends.size();i++)
3: {
4: cout << friends[i]["name"].asString() << endl;
5: }
3.轉型錯誤
1: Json::Reader *pJsonParser = new Json::Reader();
2: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\",\"sex\":\"男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";
3: Json::Value tempVal;
4: if(!pJsonParser->parse(strJson, tempVal))
5: {
6: return -1;
7: }
8: int name = tempVal["name"].asInt();
解決方法:先推斷類型。假設類型正確在取
1: if(tempVal["name"].isInt())
2: {
3:
4: int name = tempVal["name"].asInt();
5: }
對於SDK接入認證server而言。json解析全然依賴於渠道SDK傳過來的SDK,jsoncpp過於依賴json字符串,假設對端傳過來一個不合法的json,非常easy引起認證server的崩潰,所以對於SDK認證而言,採用C++來解析json是一個不太好的選擇。此外SDK中的demo一般都僅僅提供php或python的源碼。還得自己翻譯。不太划算,后面的SDK准備都採用php的方式進行接入。
Jsoncpp讀寫實例代碼
這里Mark一下jsoncpp的讀寫實例代碼:
1. Read
1: #include <iostream>
2: #include "json/json.h"
3: #include <string>
4: using namespace std;
5:
6: int main()
7: {
8: Json::Reader *pJsonParser = new Json::Reader(Json::Features::strictMode());
9: //Json::Reader *pJsonParser = new Json::Reader();
10: string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":[{\"name\":\"chen\",\"sex\":\"男\"},{\"name\":\"li\",\"sex\":\"女\"}]}";
11: //string strJson = "{\"name\":\"tom\",\"sex\":\"男\",\"age\":\"24\",\"friends\":{\'name\':\'chen\',\'sex\':\'男\'}}";
12: //string strJson = "1111 {}";
13:
14: Json::Value tempVal;
15:
16:
17: if(!pJsonParser->parse(strJson, tempVal))
18: {
19: cout << "parse error" << endl;
20: return -1;
21: }
22:
23: string name = tempVal["name"].asString();
24: string sex = tempVal["sex"].asString();
25: string age = tempVal["age"].asString();
26:
27: Json::Value friends = tempVal["friends"];
28: for(int i = 0;i < friends.size();i++)
29: {
30: cout << friends[i]["name"].asString() << endl;
31: }
32:
33: cout << "name = " << name << " age = " << age << " sex = " << sex << " friendsName " << friendsName <<endl;
34:
35: delete pJsonParser;
36:
37: return 0;
38: }
39:
2.Write
1: #include <fstream>
2: #include <cassert>
3: #include "json/json.h"
4: using namespace std;
5:
6: int main()
7: {
8: Json::Value root;
9: Json::FastWriter writer;
10: Json::Value person;
11:
12: person["name"] = "hello world";
13: person["age"] = 100;
14: root.append(person);
15:
16: std::string json_file = writer.write(root);
17:
18:
19: ofstream ofs;
20: ofs.open("test1.json");
21: assert(ofs.is_open());
22: ofs<<json_file;
23:
24: return 0;
25: }
-
Echo Chen:Blog.csdn.net/chen19870707
-
版權聲明:本文博主原創文章,博客,未經同意不得轉載。