- Author:Echo Chen(陳斌)
- Email:[email protected]
- Blog:Blog.csdn.net/chen19870707
- Date:September 28th, 2014
Explain
最近在做遊戲接入SDK時用到C++的json庫jsoncpp,jsoncpp 是一款優秀的json庫,但惡心的一點是它采用Assert作為錯誤處理方法,而assert在Linux下通過調用 abort 來終止程式運作,對于伺服器而言将會收到SIGABRT,崩潰打出core,這對于伺服器而言是緻命的,下面總結了幾種 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接入認證伺服器而言,json解析完全依賴于管道SDK傳過來的SDK,jsoncpp過于依賴json字元串,如果對端傳過來一個不合法的json,很容易引起認證伺服器的崩潰,是以對于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: }
轉載于:https://www.cnblogs.com/huojing/articles/5927488.html