最近在使用jsoncpp的库,json的概念就不多说了,这里主要是解决利用jsoncpp库提供的接口来实现满足较多类型的的json字串序列化和反序列化的封装类,通过学习之前的文章,其地址如下
http://blog.youkuaiyun.com/tragicguy/article/details/9150569
http://blog.youkuaiyun.com/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 stub
m_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;
}
测试结果如下图: