当前位置: 首页 > news >正文

【从零实现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篇 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

请添加图片描述

相关文章:

  • Apache Dubbo 与 ZooKeeper 集成:服务注册与发现的全解析
  • 复杂任务需要多agent协同处理,对其进行逻辑编排和参数调用
  • JVM 02
  • HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
  • 【leetcode hot 100 20】有效的括号
  • uniapp动态循环表单校验失败:初始值校验
  • 【学习资源】多元时序分析问题和时序图模型
  • 【机器学习】建模流程
  • uniapp笔记-swiper组件实现轮播图
  • Unicode代码点与编码
  • 好消息!软航文档控件(NTKO WebOffice)在Chrome 133版本上提示扩展已停用的解决方案
  • 【虚拟环境配置】地信从0开始的环境配置小白教程
  • python康复日记-request库的使用,爬虫自动化测试
  • 【2025】基于springboot+vue的校园创新创业竞赛平台设计与实现(源码、万字文档、图文修改、调试答疑)
  • 使用Mastra.ai构建AI智能体:一次动手实践
  • 年龄预测识别模型训练python代码
  • PostgreSQL 事务处理
  • AI大模型全攻略:原理 · 部署 · Prompt · 场景应用
  • AI本地部署之dify
  • 【LNMP】网站架构分布式部署
  • “爱泼斯坦案”关键证人弗吉尼亚·朱弗雷自杀身亡
  • 上海虹桥至福建三明直飞航线开通,飞行时间1小时40分
  • 上海未来亚洲研究会第六届会员大会举行,叶青当选会长
  • 独家丨前华金证券宏观首席秦泰加盟华福证券,任研究所副所长
  • 韩国检方起诉前总统文在寅
  • 洛阳白马寺内的狄仁杰墓挂上公示牌争论尘埃落定?瀍河区文旅局称已确认