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

本文介绍了一个用于处理JSON序列化和反序列化的C++基类CJsonObjectBase,该类能有效处理不同类型的JSON字符串,包括普通JSON字符串、包含对象的JSON字符串和包含数组对象的JSON字符串。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在使用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;
}
测试结果如下图:

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值