json介绍与使用

217 阅读4分钟

json介绍与使用

Json数据格式

Json 是⼀种数据交换格式,它采⽤完全独⽴于编程语⾔的⽂本格式来存储和表示数据。

例如: 我们想表⽰⼀个同学的学⽣信息

• C 代码表示

char *name = "xx";
int age = 18;
float score[3] = {88.5, 99, 58};

• Json 表示

 {
  "姓名" : "xx",
  "年龄" : 18,
  "成绩" : [88.5, 99, 58]
 }

 [ {"姓名":"⼩明", "年龄":18, "成绩":[23, 65, 78]},
 {"姓名":"⼩红", "年龄":19, "成绩":[88, 95, 78]}
 ]

Json 的数据类型包括对象,数组,字符串,数字等。

• 对象:使⽤花括号 {} 括起来的表⽰⼀个对象

• 数组:使⽤中括号 [] 括起来的表⽰⼀个数组

• 字符串:使⽤常规双引号 "" 括起来的表⽰⼀个字符串

• 数字:包括整形和浮点型,直接使⽤

JsonCpp介绍

Jsoncpp 库主要是⽤于实现 Json 格式数据的序列化和反序列化,它实现了将多个数据对象组织成

为 json 格式字符串,以及将 Json 格式字符串解析得到多个数据对象的功能。

序列化:将多个数据对象,按照json格式,组织成为一个字符串

反序列化:将json格式的字符串,进行解析,得到多个数据对象

先看⼀下 Json 数据对象类的表示

class Json::Value{
	Value &operator=(const Value &other); //Value重载了[]和=,因此所有的赋值和获取数据都可以通过
 	Value& operator[](const std::string& key);//简单的⽅式完成 val["name"] = "xx";
 	Value& operator[](const char* key);
	Value removeMember(const char* key);//移除元素
	const Value& operator[](ArrayIndex index) const; //val["score"][0]
	Value& append(const Value& value);//添加数组元素 val["score"].append(88); 
	ArrayIndex size() const;//获取数组元素个数 val["score"].size();
	bool isNull(); //⽤于判断是否存在某个字段
	std::string asString() const;//转string string name = val["name"].asString();
	const char* asCString() const;//转char* char *name = val["name"].asCString();
	Int asInt() const;//转int int age = val["age"].asInt();
	float asFloat() const;//转float float weight = val["weight"].asFloat();
	bool asBool() const;//转 bool bool ok = val["ok"].asBool();
};

Jsoncpp 库主要借助三个类以及其对应的少量成员函数完成序列化及反序列化

三个类:

Json::Value 类,中间数据存储对象类

想要将多个数据对象,组织成一个json字符串,就要先将数据存储到Json::Value对象中

Json::StreamWriter 类,序列化类

内部有一个成员接口实现将Json::Value中的数据序列化为一个字符串,放到一个io流中

int write(Json::Value &val, std::ostream* sout)

工厂模式:

Json::StreamWriterBuilder 是 Json::StreamWriter 的工厂类

通过工厂对象来生产产品: Json::StreamWriter* newStreamWriter()

• 序列化接⼝

class JSON_API StreamWriter {
	virtual int write(Value const& root, std::ostream* sout) = 0;
 }
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
virtual StreamWriter* newStreamWriter() const;
}

Json::CharReader 类,反序列化类

将一个json字符串,解析之后,将其中的数据对象,存储到Json::Value中

bool parse(char * start, char * end, Json::Value * root, std::string *err)

工厂模式:

Json::CharReaderBuilder 是 Json:: CharReader 的工厂类

通过工厂对象来生产产品: Json::CharReader* newCharReader()

• 反序列化接⼝

class JSON_API CharReader {
	virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {
	virtual CharReader* newCharReader() const;
}

JsonCpp功能代码⽤例编写

#include <iostream>
#include <sstream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>

int main()
{
	// 序列化
	Json::Value stu;
	stu["name"] = "zhangsan";
	stu["age"] = 19; 
	stu["socre"].append(77.5);
	stu["socre"].append(88);
	stu["socre"].append(99.5);

	Json::StreamWriterBuilder swb;
	std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());

	std::stringstream ss; 
	int ret = sw->write(stu, &ss);
	if (ret != 0) {
	std::cout << "Serialize failed!\n";
	return -1; 
	} 
	std::cout << "序列化结果:\n" << ss.str() << std::endl;

	// 反序列化
	std::string str = ss.str();
	Json::Value root;
	Json::CharReaderBuilder crb;
	std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

	bool ret1 = cr->parse(str.c_str(), str.c_str() + str.size(), &root, nullptr);
	if (!ret1) {
		std::cout << "UnSerialize failed!" << std::endl;
		return -1;
	}
	std::cout << "反序列化结果:\n"
			  << "name:" << root["name"].asString() << "\n"
			  << "age:" << root["age"].asInt() << "\n"
			  << "socre:" << root["socre"][0].asFloat() << " " << root["socre"][1].asInt()
			  << " " << root["socre"][2].asFloat() << "\n";

	return 0;
}

编译运⾏程序查看序列化和反序列化结果

[zsc@node test_jsoncpp]$ g++ test_json.cpp -o test_json -ljsoncpp -std=c++11
[zsc@node test_jsoncpp]$ ./test_json 
序列化结果:
{
	"age" : 19,
	"name" : "zhangsan",
	"socre" : 
	[
		77.5,
		88,
		99.5
	]
}
反序列化结果:
name:zhangsan
age:19
socre:77.5 88 99.5

封装Json⼯具类

#include <iostream>
#include <sstream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>
 
class json_util
{
public:
	// 序列化: Json对象 -> 字符串
	// 输⼊输出型参数
	// root输⼊参数:表⽰要序列化的json对象
	// str输出参数: 表⽰序列化之后的字符串
	static bool serialize(const Json::Value &root, std::string &str)
	{
		Json::StreamWriterBuilder swb;
		std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
        
		std::stringstream ss; 
		int ret = sw->write(root, &ss);
		if (ret != 0) {
			std::cout << "Serialize failed!" << std::endl;
			return false;
		} 
		str = ss.str();
		return true;
	}

	// 反序列化: 字符串 ->Json对象
	// 输⼊输出型参数
	// str输⼊参数: 表⽰需要反序列化的字符串
	// root输出参数:表⽰反序列化后的json对象
	static bool unserialize(const std::string &str, Json::Value &root)
	{
		Json::CharReaderBuilder crb;
		std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

		bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &root, nullptr);
		if (!ret) {
			std::cout << "UnSerialize failed!" << std::endl;
			return false;
		}
		return true;
	}
};