利用jsoncpp接口来实现json字串的序列化与反序列化的C++封装类

来源:互联网 发布:科比0506常规赛数据 编辑:程序博客网 时间:2024/05/16 03:39

最近在使用jsoncpp的库,json的概念就不多说了,这里主要是解决利用jsoncpp库提供的接口来实现满足较多类型的的json字串序列化和反序列化的封装类,通过学习之前的文章,其地址如下

http://blog.csdn.net/tragicguy/article/details/9150569

http://blog.csdn.net/tragicguy/article/details/9153121
根据自己的需求,给出一个C++处理json序列化和反序列化的基类,能够处理普通json字串,包含对象的json字串和包含数组对象的json字串,
其.h文件如下:
#ifndef JSONHANDLE_CJSONOBJECTBASE_H_#define JSONHANDLE_CJSONOBJECTBASE_H_#include <string>#include <vector>#include <list>#include "json/json.h"#include "baseTypeDef.h"/* 各种json对象的标识 */typedef enum{asBool= 1,asInt16,//asUnt16,asInt,asUInt,asString,asInt64,asUInt64,asJsonObj,             //复杂对象asArray,              //数组jsonNum                  //标识数}E_JsonType;class CJsonObjectBase{public:CJsonObjectBase();virtual ~CJsonObjectBase();public:std::string Serialize();            /* 序列化为json结构 */bool DeSerialize(const char* str);  /* 反序列化为内存变量 */Json::Value DoArraySerialize(std::vector<CJsonObjectBase*> *pList);     /* 对数组结构进行 */void SetProperty(std::string name, E_JsonType type, void* addr);void SetPropertyObj(std::string name, E_JsonType type, void* addr, E_JsonType listParamType = asInt);private:Json::Value DoSerialize();bool DoDeSerialize(Json::Value& root);bool DoObjArrayDeSerialize(const std::string& propertyName, void* addr, Json::Value& node);virtual CJsonObjectBase* GenerateJsonObjForDeSerialize(const std::string& propertyName){    return NULL;};virtual void SetPropertys() = 0;private:std::vector<std::string>   m_listName;std::vector<void*>         m_listPropertyAddr;std::vector<E_JsonType>   m_listType;std::vector<E_JsonType>    m_listParamType;};#endif /* JSONHANDLE_CJSONOBJECTBASE_H_ */
.cpp文件如下
#include "CJsonObjectBase.h"CJsonObjectBase::CJsonObjectBase(){// TODO Auto-generated constructor stubm_listName.clear();m_listParamType.clear();m_listPropertyAddr.clear();m_listType.clear();}CJsonObjectBase::~CJsonObjectBase(){// TODO Auto-generated destructor stub}std::string CJsonObjectBase::Serialize(){std::string out;Json::Value new_item = DoSerialize();Json::FastWriter writer;out = writer.write(new_item);return out;}Json::Value CJsonObjectBase::DoSerialize(){Json::Value new_item;int nSize = m_listName.size();for (int i = 0; i < nSize; ++i){void *pAddr = m_listPropertyAddr[i];switch (m_listType[i]){case asArray:{new_item[m_listName[i]] = DoArraySerialize((std::vector<CJsonObjectBase*>*)(pAddr));break;}case asJsonObj:{new_item[m_listName[i]] =((CJsonObjectBase*) pAddr)->DoSerialize();break;}case asBool:{new_item[m_listName[i]] = (*(bool*) pAddr);break;}case asInt16:{new_item[m_listName[i]] = (*(Int16*) pAddr);break;}case asInt:{new_item[m_listName[i]] = (*(Int32*) pAddr);break;}case asUInt:{new_item[m_listName[i]] = (*(Uint32*) pAddr);break;}case asInt64:{//TODO  JSON 无法处理long类型break;}case asUInt64:{//TODO  JSON 无法处理long类型break;}case asString:{new_item[m_listName[i]] = (*(std::string*) pAddr);break;}default:{break;}}}return new_item;}Json::Value CJsonObjectBase::DoArraySerialize(std::vector<CJsonObjectBase*> *pList){Json::Value arrayValue;for (std::vector<CJsonObjectBase*>::iterator iter = pList->begin(); iter != pList->end(); ++iter){arrayValue.append((*iter)->DoSerialize());}return arrayValue;}bool CJsonObjectBase::DoObjArrayDeSerialize(const std::string& propertyName, void* addr, Json::Value& node){if (!node.isArray()){return false;}std::vector<CJsonObjectBase*> *pList = (std::vector<CJsonObjectBase*>*)addr;int size = node.size();for (int i = 0; i < size; ++i){CJsonObjectBase* pNode = GenerateJsonObjForDeSerialize(propertyName);pNode->DoDeSerialize(node[i]);pList->push_back(pNode);}return true;}/* 反序列化的对外接口 */bool CJsonObjectBase::DeSerialize(const char *str){Json::Reader reader;Json::Value root;if (reader.parse(str, root)){return DoDeSerialize(root);}return false;}/* 反序列化的具体实现接口 */bool CJsonObjectBase::DoDeSerialize(Json::Value &root){    int nSize = m_listName.size();    for (int i = 0; i < nSize; ++i)    {        void* pAddr = m_listPropertyAddr[i];        switch (m_listType[i])        {            case asArray:            {                if (root.isNull() || root[m_listName[i]].isNull())                {                    break;                }                DoObjArrayDeSerialize(m_listName[i], pAddr, root[m_listName[i]]);                break;            }            case asJsonObj:            {                if (!root[m_listName[i]].isNull())                    ((CJsonObjectBase*) pAddr)->DoDeSerialize(                            root[m_listName[i]]);                break;            }            case asBool:            {                (*(bool*) pAddr) = root.get(m_listName[i], 0).asBool();                break;            }            case asInt16:            {                (*(Int32*) pAddr) = root.get(m_listName[i], 0).asInt();                break;            }            /* todo asUint16类型的处理 */            case asInt:            {                (*(Int32*) pAddr) = root.get(m_listName[i], 0).asInt();                break;            }            case asUInt:            {                (*(Uint32*) pAddr) = root.get(m_listName[i], 0).asUInt();                break;            }            case asInt64:            {                (*(Int64*) pAddr) = root.get(m_listName[i], 0).asInt64();                break;            }            case asUInt64:            {                (*(Uint64*) pAddr) = root.get(m_listName[i], 0).asUInt64();                break;            }            case asString:            {                (*(std::string*) pAddr) =                        root.get(m_listName[i], "").asString();                break;            }            //我暂时只支持这几种类型,需要的可以自行添加            default:            {                break;            }        }    }    return true;}void CJsonObjectBase::SetProperty(std::string name, E_JsonType type, void* addr){    m_listName.push_back(name);    m_listPropertyAddr.push_back(addr);    m_listType.push_back(type);}void CJsonObjectBase::SetPropertyObj(std::string name, E_JsonType type, void* addr, E_JsonType listParamType ){    m_listName.push_back(name);    m_listPropertyAddr.push_back(addr);    m_listType.push_back(type);    m_listType.push_back(listParamType);}
测试程序如下:
#include <iostream>#include "JsonHandle/CJsonObjectBase.h"using namespace std;/* 一条记录 */class Record : public CJsonObjectBase{public:Record(){SetPropertys();}virtual ~Record(){}void setId(int i){recordId = i;}private:virtual void SetPropertys(){SetProperty("recordId", asInt, &recordId);}int recordId;};class MsgInfo : public CJsonObjectBase{public:MsgInfo(int id, string type, std::vector<Record*> &re): msgId(id), type(type), recordTable(re){SetPropertys();}MsgInfo(){}virtual ~MsgInfo(){for (std::vector<Record*>::iterator it = recordTable.begin(); it != recordTable.end(); ++it){delete (*it);}}CJsonObjectBase* GenerateJsonObjForDeSerialize(const std::string& propertyName){if ("recordTable" == propertyName){return new Record();}return NULL;}private:virtual void SetPropertys(){SetProperty("msgId", asInt, &msgId);SetProperty("type", asString, &type);SetPropertyObj("recordTable", asArray, &recordTable, asJsonObj);}std::vector<Record*> recordTable;int msgId;std::string type;};class PlayInfo : public CJsonObjectBase{public:PlayInfo(int id, string ip, MsgInfo &message) : playId(id), clientIp(ip), msg(message){SetPropertys();}virtual ~PlayInfo(){}string getip(){return clientIp;}int getid(){return playId;}private:virtual void SetPropertys(){     SetProperty("playId", asInt, &playId);     SetProperty("clientIp", asString, &clientIp);     SetProperty("msgInfo", asJsonObj, &msg);}int playId;std::string clientIp;MsgInfo msg;};int main(){Record *r1 = new Record();r1->setId(1);Record *r2 = new Record();r2->setId(3);std::vector<Record*> recordTable;recordTable.push_back(r1);recordTable.push_back(r2);MsgInfo *pMsgInfo = new MsgInfo(1, "info", recordTable);cout << pMsgInfo->Serialize() << endl;PlayInfo *pPlayInfo = new PlayInfo(1, "192.168.1.255", (*pMsgInfo));cout << "playInfo:" << pPlayInfo->Serialize() << endl;return 0;}
测试结果如下图: