【Linux】【网络】协议:(序列化和反序列化)json 的安装和简单使用

1. 下载 json

yum makecache fast
yum -y install jsoncpp-devel

安装检测:注意对于 Linux 不同版本下文件名可能不同

 ls /usr/include/jsoncpp/json/

在这里插入图片描述

ls /usr/lib64/libjson*

在这里插入图片描述

2. 基本使用

  • 头文件:
#include <jsoncpp/json/json.h>
  • 编译时需要加上:
-ljsoncpp

2.1 组织数据的格式

json 数据类型:对象,数组,字符串,数字

  • 对象:使用花括号 {} 括起来的表示一个对象。
  • 数组:使用中括号 [] 括起来的表示一个数组。
  • 字符串:使用常规双引号 "" 括起来的表示一个字符串
  • 数字:包括整形和浮点型,直接使用

🌰例如正常组织一个人的信息:

char name = "Kevin";
int age = 30;
float score[3] = {12, 15, 24};

json 这样组织:

[
	{
		"name": "Kevin", 
		"age": 30, 
		"score": [12, 15, 24]
	},
	{
		"name": "Stella", 
		"age": 20,
		"score": [16, 18, 23]
	}
]

2. 2 Json::Value 数据对象类:万能类型

  • json::value:是一种万能对象类型,能接收任意 kv 类型,储存的值会自动转成 字符串类型

  • 使用 中括号 [] 进行 定义拿取

  • asxxx():使用中括号可以对内容进行提取后,val[yy].asxxx() 可以转化数据类型为 xxx

具体如下:

class Json::Value{
	// 【重载 [] 和 =】,因此所有的赋值和获取数据都可以通过简单的方式完成 val["name"] = "kevin";
    Value &operator=(const Value &other); 
    Value& operator[](const std::string& key);
    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(30); 
    ArrayIndex size() const;//获取数组元素个数 val["score"].size();
	
	// 【数据格式化转换】
    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
    bool asBool() const;			//转成bool
};

2.3 序列化/反序列化 类(低版本)

使用更简单

序列化(低版本

class JSON_API Writer {
	virtual std::string write(const Value& root) = 0;
}
class JSON_API FastWriter : public Writer {
	virtual std::string write(const Value& root);
 }
class JSON_API StyledWriter : public Writer {
	virtual std::string write(const Value& root);
}
  • json::FastWriter 类:用于快速序列化的数据类型,即,可以将 struct 转成 string,用于传输
  • json::StyleWriter 类:也是用于序列化的数据类型,格式更加清楚美观
  • write() 接口:将 value 类,以序列化 string 格式,写入网络

反序列化(低版本

class JSON_API Reader {
	bool parse(const std::string& document, Value& root, bool collectComments = true);
}
  • json::Reader 类:用于反序列化的数据类型,即,可以将从网络接收到的 stirng 转成 struct,用于业务处理
  • parse() 接口:从相应的流(网络)里面,将 string 信息读取到 json::Value 中去

2.4 序列化/反序列化 类(高版本)

如果高版本使用低版本的接口可能会有警告

序列化(高版本

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::StreamWriter 类:用工厂实例化对象进行建造
  • write() 接口:将 value 类,以序列化 string 格式,写入网络

反序列化(高版本

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;
}
  • json::CharReader 类:用工厂实例化对象进行建造
  • parse() 接口:从相应的流(网络)里面,将 string 信息读取到 json::Value 中去

2.5 简单使用

🌰序列化:

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

int main()
{
	const char *name = "Kevin";
	int age = 30;
	float score[3] = {12, 15, 24};
	
	Json::Value root;
	root["name"] = name;
	root["age"] = age;
	root["score"].append(score[0]);
	root["score"].append(score[1]);
	root["score"].append(score[2]);
	
	Json::StreamWriterBuilder swb;
	std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
	std::stringstream ss;
	sw->writer(root, &ss);
	std::cout << ss.str() << std::endl;

	return 0;
}

-------------
输出结果:
{
	"age" : 30,
	"name" : "kevin",
	"score" : 
	[
		12,
		15,
		24
	]
}

🌰反序列化:

/*	
virtual bool parse(char const* beginDoc, char const* endDoc, 
                       Value* root, std::string* errs) = 0;
*/
#include <iostream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>
	
int main()
{
	std::string str = R"({"name":"Stella", "age":20, "score": [16, 18, 23]})";  // C++11用法,R():圆括号内都是原始字符串
	
	Json::Value root;
	Json::CharReaderBuilder crb;
	std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
	std::string errstr;
	bool ret = cr->parse(str.c_str(), str.c_str() + str.size(), &root, &errstr);
	if(ret == false)
	{
		std::cerr << "parse error:" << errstr << std::endl;
		return -1;
	}
	
	std::cout << root["name"].asString() << std::endl;
	std::cout << root["age"].asInt() << std::endl;                                            
	int sz = root["score"].size();
	for(int i = 0; i < sz; i++)
	{
		std::cout << root["score"][i] << std::endl;
	}
	
	return 0;
}


-------------
输出结果:
Stella
20
16
18
23

3. 使用举例

🌰此处举例协议内容为:整数的加减乘除取模的运算及输出方式。

// 【请求】
class Request
{
public:
    Request() {}
    Request(int x, int y, char op) : _x(x), _y(y), _op(op)
    {
    }
    // struct->string
    // "_x _op _y"
    bool Serialize(std::string *outStr)
    {
        *outStr = "";
        Json::Value root; 
        
        root["x"] = _x; 
        root["y"] = _y;
        root["op"] = _op;
        Json::StyledWriter writer;	// Json::FastWriter writer; 
        *outStr = writer.write(root);
        return true;
    }
    // string->struct
    bool Deserialize(const std::string &inStr)
    {
        Json::Value root;
        Json::Reader reader; 
        reader.parse(inStr, root);

        _x = root["x"].asInt();     // json::Value root 里面全是string,需要类型转换一下
        _y = root["y"].asInt();
        _op = root["op"].asInt();   // op也转成int,放入char里会被解释成操作符
        return true;
    }
    ~Request() {}

public:
    int _x;
    int _y;
    char _op;
};

// 【响应】
class Response
{
public:
    Response() {}
    Response(int result, int code) : _result(result), _code(code)
    {
    }
    // struct->string
    bool Serialize(std::string *outStr)
    {
        *outStr = "";
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        // Json::FastWriter writer;
        Json::StyledWriter writer;

        *outStr = writer.write(root);
        return true;
    }
    // string->struct
    bool Deserialize(const std::string &inStr)
    {
        Json::Value root;
        Json::Reader reader;
        reader.parse(inStr, root);
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
    }
    ~Response() {}

public:
    int _result;	// 计算结果
    int _code; 		// 正确和错误码
};

🥰如果本文对你有些帮助,请给个赞或收藏,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 欢迎评论留言~~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值