【从零实现Json-Rpc框架】- 第三方库介绍 - jsoncpp篇
📢博客主页:https://blog.csdn.net/2301_779549673
📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨
文章目录
- 📢前言
- 🏳️🌈 1 JsonCpp库
- 1.1 Json数据格式
- 1.2 JsonCpp介绍
- 1.3 JsonCpp的封装
- 1.4 JsonCpp的使用
- 👥总结
📢前言
紧接上回,接下来笔者将介绍rpc框架的最重要的三个第三方库,方便大家理解
这回是 jsoncpp 篇
四、
🏳️🌈 1 JsonCpp库
1.1 Json数据格式
Json 是⼀种数据交换格式,它采⽤完全独⽴于编程语⾔的⽂本格式来存储和表⽰数据
C 代码表示
char *name = "xx";
int age = 18;
float score[3] = {88.5, 99, 58};
Json表示
{
"姓名" : "xx",
"年龄" : 18,
"成绩" : [88.5, 99, 58],
"爱好" :{
"书籍" : "西游记",
"运动" : "打篮球"
}
}
- Json 的数据类型包括对象,数组,字符串,数字等。
对象:使用花括号 {}
括起来的表示一个对象
数组:使用中括号[]
括起来的表示一个数组
字符串:使用常规双引号""
括起来的表示一个字符串
数字:包括整形和浮点型,直接使用
1.2 JsonCpp介绍
Jsoncpp
库主要是用于实现 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();
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 库主要借助三个类以及其对应的少量成员函数完成序列化及反序列化
序列化接口
/**
* @brief JSON流式写入器抽象接口
*
* 定义统一的JSON数据流式写入接口,子类需实现具体的序列化逻辑(如格式化、编码等)
*/
class JSON_API StreamWriter { // JSON_API 通常用于跨库导出符号(如DLL导出)
public:
/**
* @brief 将JSON Value对象写入输出流
* @param root 待写入的JSON根节点
* @param sout 输出流目标(例如文件流、字符串流等)
* @return 操作状态码(通常0表示成功,非0为错误码)
*/
virtual int write(Value const& root, std::ostream* sout) = 0; // 纯虚函数,接口类
};
/**
* @brief StreamWriter的工厂类
*
* 实现工厂模式,用于创建特定配置的StreamWriter实例。
* 可通过派生此类实现不同的构建策略(如配置缩进、编码方式等)
*/
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
public:
/**
* @brief 创建新的StreamWriter实例
* @return StreamWriter* 实例指针,调用者需管理内存
*/
virtual StreamWriter* newStreamWriter() const override;
// 通常在此类中添加构建配置方法,例如:
// void setIndentSize(int size); // 设置缩进大小
// void enableUTF8(bool enable); // 启用UTF8编码
};
反序列化接口
/**
* @brief JSON字符流解析器接口
*
* 定义从原始字符流解析JSON数据的统一接口,子类实现具体解析逻辑(如严格模式/宽松模式)
*/
class JSON_API CharReader { // JSON_API 通常用于跨库导出(如DLL导出)
public:
/**
* @brief 解析JSON字符流
* @param beginDoc 字符流起始指针(包含JSON文本)
* @param endDoc 字符流结束指针(指向最后一个字符的下一位)
* @param root [out] 解析后的JSON根节点存储位置
* @param errs [out] 错误信息输出缓冲区
* @return true解析成功,false解析失败(错误详情存入errs)
*/
virtual bool parse(char const* beginDoc, char const* endDoc,
Value* root, std::string* errs) = 0; // 纯虚函数,接口类
};
/**
* @brief CharReader的工厂类
*
* 用于创建配置化的JSON解析器实例,支持设置解析选项(如注释允许、尾逗号忽略等)
*/
class JSON_API CharReaderBuilder : public CharReader::Factory {
public:
/**
* @brief 创建新的解析器实例
* @return CharReader* 调用者需负责释放内存
*/
virtual CharReader* newCharReader() const override;
// 典型配置方法示例:
// void allowComments(bool allow); // 允许JSON注释
// void setStrictMode(bool strict); // 严格模式校验
};
1.3 JsonCpp的封装
就比如说这是两个封装序列化与反序列化的基本例子
// 实现数据的序列化
bool serialize(const Json::Value& val, std::string& body){
std::stringstream ss;
// 先实例化一个工厂类对象
Json::StreamWriterBuilder swb;
// 通过工厂类对象来生产派生类对象
std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
// 利用sw的write方法将val序列化到ss中
int ret = sw->write(val, &ss);
if(ret != 0){
std::cout << "write json data error" << std::endl;
return false;
}
body = ss.str();
return true;
}
// 实现json数据的反序列化
bool unserialize(const std::string& body, Json::Value& val){
// 实例化工厂类对象
Json::CharReaderBuilder crb;
// 生产CharReader对象
std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
// 记录错误信息
std::string errs;
// 利用cr的parse方法将body反序列化到val中
bool ret = cr->parse(body.c_str(), body.c_str(), &val, &errs);
if(ret == false){
std::cout << "parse json data error: " << errs << std::endl;
return false;
}
return true;
}
1.4 JsonCpp的使用
int main(){
const char* name = "小明";
int age = 18;
const char* sex = "男";
float score[3] = {80, 90.5, 95};
Json::Value student;
student["姓名"] = name;
student["年龄"] = age;
student["性别"] = sex;
student["成绩"].append(score[0]);
student["成绩"].append(score[1]);
student["成绩"].append(score[2]);
Json::Value fav;
fav["书籍"] = "西游记";
fav["运动"] = "打篮球";
student["喜好"] = fav;
std::string body;
serialize(student, body);
std::cout << body << std::endl;
std::string str = R"({"姓名":"小红","年龄":19,"性别":"女","成绩":[85,92,98],"喜好":{"书籍":"红楼梦","运动":"游泳"}})";
Json::Value stu;
bool ret = unserialize(str, stu);
if(ret == false)
return -1;
std::cout << "姓名:" << stu["姓名"].asString() << std::endl;
std::cout << "年龄:" << stu["年龄"].asInt() << std::endl;
std::cout << "性别:" << stu["性别"].asString() << std::endl;
std::cout << "成绩:" << stu["成绩"][0].asFloat() << " " << stu["成绩"][1].asFloat() << " " << stu["成绩"][2].asFloat() << std::endl;
std::cout << "喜好:" << stu["喜好"]["书籍"].asString() << " " << stu["喜好"]["运动"].asString() << std::endl;
return 0;
}
👥总结
本篇博文对 【从零实现Json-Rpc框架】- 第三方库介绍 - jsoncpp篇 做了一个较为详细的介绍,不知道对你有没有帮助呢
觉得博主写得还不错的三连支持下吧!会继续努力的~