json协议-rapidjson

rapidjson常规用法

官方文档地址: rapidjson文档

1. rapidjson 安装

rapidjson下载之后,将原项目中include文件夹拷贝到自己项目的include文件夹下即可,不需要再编译为静态库或动态库。

2. 序列化与反序列化

2.1生成json对象

例如目标json格式为:

{
  "env_name": "测试",
  "node_name": "centos7",
  "dns_time": 0.2,
  "max_wait_time": 5,
  "redirect": true,
  "target_link": [
    "1.0.0.0:1410",
    "1.0.0.1:1411"
  ],
  "redirect_details": {
    "bj": "0.0.0.0",
    "sh": "0.0.0.1"
  },
  "null_obj":{}
}

生成json对象:

void product(rapidjson::Document& doc){
    // 相比于jsoncpp,rapidjson的内存分配是需要显示给出的;构造doc时也可以传入一个分配器
    // 而jsoncpp内部是大多是调用new delete进行内存分配 
    // 这也就说明,allocator作为Document类的属性,在析构的时候才会释放,若是外部传入的参数需要注意多次释放的问题
    
    rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> & allocator = doc.GetAllocator();
    doc.SetObject();
    doc.AddMember("env_name", "测试", allocator);
    doc.AddMember("node_name", "centos7", allocator);
    doc.AddMember("dns_time", 0.2, allocator);
    doc.AddMember("max_wait_time", 5, allocator);
    doc.AddMember("redirect", true, allocator);

    // 添加数组
    rapidjson::Value arr(rapidjson::kArrayType);
    arr.PushBack("1.0.0.0:1410",allocator);
    arr.PushBack("1.0.0.0:1410",allocator);
    doc.AddMember("target_link", arr, allocator);

    // 添加对象
    rapidjson::Value obj(rapidjson::kObjectType);
    obj.AddMember("bj","0.0.0.0",allocator);
    obj.AddMember("sh","0.0.0.1",allocator);
    doc.AddMember("redirect_details", obj, allocator);

    doc.AddMember("null_obj", rapidjson::kObjectType, allocator);
}

2.2 获取json对象的值

  • 根据key获取值
void read_json(rapidjson::Document& doc){
    if(doc.HasMember("env_name") && doc["env_name"].IsString()){
        std::clog << "env_name:" << doc["env_name"].GetString() << std::endl; 
    }
    #ifdef TEST
    // jsoncpp对于不存在的key,可以使用[]操作符,返回的是null类型
    // rapidjson的[]操作符返回的是引用,对于不存在的key,直接引用会core
    // rapidjson::Value& tmp = doc["env_name_"];
    //std::clog << doc["env_name_"].GetString() << std::endl;
    #endif
    if(doc.HasMember("target_link") && doc["target_link"].IsArray()){
        for(auto itr = doc["target_link"].Begin(); itr!=doc["target_link"].End();++itr){
            std::clog << "target_link:" << itr->GetString() << std::endl;
        }
    }
}
  • 类jsonpath抽取
    相比于jsoncpp的Path类,rapidjson中提供了更丰富的Point模板实例,可以根据Point进行抽取和生成
 // Point
rapidjson::Pointer point("/target_link/0");
std::clog << "point value=" << point.Get(doc)->GetString() << std::endl;

2.3 写入字符串

rapidjson是漠然支持UTF8编码

  • 由Json对象生成字符串
void writer_str(rapidjson::Document& doc, bool style = false){
    rapidjson::StringBuffer buf;
    if(!style){
      rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
      doc.Accept(writer);
      std::clog << buf.GetString() << std::endl;
      return;
    }
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);
    doc.Accept(writer);
    std::clog << buf.GetString() << std::endl;
}
  • 直接生成json字符串
std::string product_direct(){
  rapidjson::StringBuffer buf;
  // rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
  rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);

  writer.StartObject();
  writer.Key("env_name"); writer.String("测试");
  writer.Key("node_name"); writer.String("centos7");
  writer.Key("dns_time"); writer.Double(0.2);
  writer.Key("max_wait_time"); writer.Int(5);
  writer.Key("redirect"); writer.Bool(true);

  writer.Key("target_link");
  writer.StartArray();
  writer.String("1.0.0.0:1410");
  writer.String("1.0.0.0:1410");
  writer.EndArray();

  writer.Key("redirect_details");
  writer.StartObject();
  writer.Key("bj"); writer.String("0.0.0.0");
  writer.Key("sh"); writer.String("0.0.0.1");
  writer.EndObject();

  writer.Key("null_obj");
  writer.StartObject();
  writer.EndObject();

  writer.EndObject();

  return buf.GetString();

}

2.4 解析json文件

rapidjson解析文件官方说明: 文件流,提供了多种流的输入方式, 例如使用iostream的包装类 ISatreamWrapper.

void parse_file(const std::string file_name){
  std::ifstream file(file_name, std::ios::in | std::ios::binary);
  if(!file.is_open()) return;
  // Document可以指定编码,默认未UTF8
  // rapidjson::GenericDocument<rapidjson::UTF16<>> utr16_doc;
  rapidjson::Document doc;
  rapidjson::IStreamWrapper input_stream(file);
  doc.ParseStream(input_stream);
  if(doc.HasParseError()) return;
  std::clog << doc.GetString() << std::endl;
}

3. rapidjson内存分配器

源码中的allocators.h文件中描述了内存分配相关内容。

rapidjson内存分配器

  • MemoryPoolAllocator 采用引用计数共享数据,使用带有头节点的链表管理内存节点,默认每个节点大小64K
  • 初始化时 shared_节点和 ChunkHeader节点在内存上是连续的;后续申请内存时,到shared_指向的Chunk中申请,若是大小溢出,则申请新的节点,新节点挂在链表头部,shared_指针指向最新节点。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值