前言:json是一种很简洁的协议。可惜的是他只能传递基本的数据类型(例如int/long/string)这种,本身不支持二进制数据(不能传递byte类型)。
换句话说json本身是不支持二进制数据传输的。
举个例子。你可能会遇到用json传递protobuf对象的情况;一个看起来可行的方案是 对pb对象序列化后把序列化后的二进制流直接赋给json的某个字段;传输到对端后对端取到二进制流再反序列换成pb对象。但实际操作后你就会发现这样是行不通的。同理传输图片等二进制文件也是行不通的。
解决办法:一个可行的方案就是将二进制数据进行转换,只要转换后的数据能用json的字符串表示即可。显然base64就是一种基于64个可见字符来表示二进制数据的方法。所以一个可行的解决方案就是对byte[]进行base64编码转换成字符串,接收端再decode得到原byte[]即可。
缺点:缺点也是很明显的。①性能方面。Base64有着较高的处理开销。 ②空间方面。base64将3个字节扩展为4个字符,导致数据大小膨胀约33%。
安装JsonCpp需要下载JsonCpp和Scon还需要机器上有python
scons又是一个牛叉的工具,功能和GNU make一样,又比make简单多了。scons是python工具,需要先安装好python。
验证python是否安装以及安装版本的指令为:python --version
0、scons简介:
Scons是一个开放源码、以Python语言编码的自动化构建工具,可用来替代make编写复杂的makefile。并且scons是跨平台的,只要scons脚本写的好,可以在Linux和Windows下随意编译。
scons 的设计目标就是让开发人员更容易、更可靠和更快速的建造软件。
与传统的 make 工具比较,scons 具有以下优点:
(1)使用 Python 脚本做为配置文件
(2)对于 C,C++ 和 Fortran, 内建支持可靠自动依赖分析 . 不用像 make 工具那样需要 执行"make depends"和"make clean"就可以获得所有的依赖关系。
(3)内建支持 C, C++, D, Java, Fortran, Yacc, Lex, Qt,SWIG 以及 Tex/Latex。 用户还可以根据自己的需要进行扩展以获得对需要编程语言的支持。
(4)支持 make -j 风格的并行建造。相比 make -j, scons可以同时运行 N 个工作,而不用担心代码的层次结构。
(5)使用 Autoconf 风格查找头文件,函数库,函数和类型定义。
(6)良好的夸平台性。scons 可以运行在 Linux, AIX, BSD, HP/UX, IRIX, Solaris, Windows, Mac OS X 和 OS/2 上。
一句话:scons是make的同类产品,也可以看做升级产品。它做的事情跟make一样,但更简单,更容易。
1、下载地址:
Jsoncpp下载:https://sourceforge.net/projects/jsoncpp/
Scons下载:https://sourceforge.net/projects/scons/
注意:对于jsoncpp最好安装高版本,如0.10.6这种。对于0.5.0这种低版本不支持UInt64、Int64这种数据。
2.解压并配置SCons
将下载的 Scons压缩包,进行解压:
$tar -zxvf scons-3.1.1.tar.gz
配置环境变量:
export SCONS_PATH=/jsoncpp/scons-3.1.1
export SCONS_LIB_DIR=$SCONS_PATH/engine
3.解压配置Jsoncpp
将下载的 jsoncpp压缩包,进行解压:
$tar zxvf jsoncpp-src-0.5.0.tar.gz
配置环境变量:
export JSONCPP_PATH=/jsoncpp/jsoncpp-src-0.5.0
注:配置环境变量的几种方法这里在说一下。
1、用export命令,直接执行 export JSONCPP_PATH=/jsoncpp/jsoncpp-src-0.5.0 指令。
2、修改profile文件,vim /etc/profile,输入export语句。
source /etc/profile #注意执行本指令来生效
echo $SCONS_PATH #来验证SCONS_PATH这个环境变量在当前终端是否生效。
3、修改.bashrc文件,输入vim /root/.bashrc,输入export语句。
注意:对于jsoncpp最好安装高版本,如0.10.6这种。对于0.5.0这种低版本不支持UInt64、Int64这种数据。
jsoncpp-0.10.6版本安装:
//获取安装包
wget https://github.com/open-source-parsers/jsoncpp/archive/0.10.6.zip
unzip jsoncpp-0.10.1.zip
//进入路径
cd jsoncpp-0.10.1
mkdir -p ./build/debug
cd ./build/debug
//cmake
//以下gcc 或者 g++ 的路径最好which确认下再填上去
cmake \
-D CMAKE_BUILD_TYPE=debug \
-D BUILD_STATIC_LIBS=ON \
-D BUILD_SHARED_LIBS=OFF \
-D CMAKE_INSTALL_PREFIX=/usr/local/jsoncpp \
-D CMAKE_C_COMPILER=/usr/bin/gcc \
-D CMAKE_CXX_COMPILER=/usr/bin/g++ \
-G "Unix Makefiles" ../..
//编译和安装
make && make install
4.编译Jsoncpp
我的jsoncpp目录在/jsoncpp/jsoncpp-src-0.5.0
cd jsoncpp-src-0.5.0
python $SCONS_PATH/script/scons platform=linux-gcc
注释:网上有一些错误的 也可能是早期的版本 ,如下:
经过测试 发现报错 查看路径下 没有scons.py文件 故改为scons
python $SCONS_PATH/src/script/scons.py platform=linux-gcc #这个会出错
编译 完成后就会在jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5目录下生成静态和动态库文件。如下:
5.举例
创建jsoncpptest.cpp文件,内容如下:
#include "json/json.h"
#include
#include
using namespace std;
int main()
{
string test ="{\"id\":1,\"name\":\"kurama\"}";
//string test = "{\"id\": 1, \"name\": \"张三\", \"age\": 18, \"sister\": [{\"name\": \"张大姐\", \"age\": 30}, {\"name\": \"张二姐\", \"age\": 20}]}";
Json::Reader reader;
Json::Value value;
if(reader.parse(test,value))
{
if(!value["id"].isNull())
{
cout<
我的jsoncpp目录在/jsoncpp/jsoncpp-src-0.5.0,故编译指令如下:
g++ jsoncpptest.cpp -I /jsoncpp/jsoncpp-src-0.5.0/include -L /jsoncpp/jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5/ -ljson_linux-gcc-4.8.5_libmt
./a.out时错误,说是找不到.so文件,报错如下:
如下解决方法均可:
1.将jsoncpp编译后的.so文件拷贝到当前项目目录中;
2.编辑/etc/ld.so.conf文件,将.so文件所在的路径加进去,同时加入/usr/local/lib
/jsoncpp/jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5
/usr/local/lib
然后用如下命令对.so的配置进行更新
/sbin/ldconfig -v
编译业务程序:
编译业务程序其实很简单。跳转到jsoncpp编译路径下的/pkg-config(即/jsoncpp/jsoncpp-0.10.6/build/debug/pkg-config)。
我们编译业务方程序需要的无非是 -L${libdir} 、-ljsoncpp 和-I${includedir};而这些 jsoncpp.pc 文件中全有。于是就可以得到:
g++ jsontest.cpp -o jsontest -I /usr/local/jsoncpp/include/jsoncpp -L /usr/local/jsoncpp/lib -ljsoncpp
举例二
创建如下jsontest.cpp文件。这个实例包含了json的诸多用法。
#include
#include
#include
#include
#include
#include
#include
#include "json/json.h"
using namespace std;
int main(int argc, char **argv) {
Json::Value root;
Json::Value header;
Json::Value arrayObj;
Json::Value item;
//Json头信息
header["pro"] = "17";
header["service_type"] = "GPS11";
cout << "*************读取普通文件生成json************" << endl;
//open文件
char buffer[256];
ifstream in("test.txt");
int i = 0;
if (! in.is_open())
{
cout << "Error opening file";
exit (1);
}
while (!in.eof() )
{
in.getline (buffer,100);
item[buffer] = i;
i++;
arrayObj.append(item);
item.clear();
}
root["HEADER"] = header;
root["BODYLIST"] = arrayObj;
std::string out = root.toStyledString();
std::cout << out << std::endl;
in.close();
cout << "*****************Writer的用法******************" << endl;
Json::Value person;
person["name"]="shuozhuo";
person["sex"]="male";
person["age"]=26;
Json::Value family;
family["address"]="anhui";
family["number"]=4;
Json::Value occupation;
occupation["occupation"]="engineer";
occupation["company_name"]="tencent";
occupation["company_address"]="shanghai";
Json::Value other_info;
//other_info.append(family);
//other_info.append(occupation);
other_info["occupation"]= occupation;
other_info["family"]=family;
person["other_info"]=other_info;
cout << "***********无style格式的输出*************" << endl;
//json转换成json字符串,无格式化输出。所谓无格式输出就是没有缩进当成一个字符串的输出。
Json::FastWriter fast_writer;
string str1=fast_writer.write(person);
cout << "str1=" << str1 << endl;
cout << "********style格式的输出(方法一)*********" << endl;
//json转换成json字符串,有格式化输出。所谓有格式输出就是错落有致的输出。
Json::StyledWriter style_writer;
string str2=style_writer.write(person);
cout << "str2" << str2 << endl;
cout << "********style格式的输出(方法二)*********" << endl;
cout << person.toStyledString() << endl;
cout << "*************生成json文件***************" << endl;
Json::StyledStreamWriter stream_writer;
ofstream ofs("stream_writer.json");
stream_writer.write(ofs,person);
ofs.close();
cout << "**********Reader的用法(Reader)**********" << endl;
ifstream jsonfile("stream_writer.json");
Json::Value value_read;
Json::Reader reader;
if(!reader.parse(jsonfile,value_read)){
cout << "parse error!!" << endl;
}else{
cout << "parse success!!" << endl;
cout << value_read["name"].asString() << endl;
cout << value_read["age"].asInt() << endl;
cout << value_read["other_info"]["family"]["number"].asInt() << endl;
}
cout << "********判断key是否存在(isMember)********" << endl;
if(value_read.isMember("sex")){
cout << "sex is member" << endl;
}else
{
cout << "sex is not member" << endl;
}
if(value_read.isMember("high")){
cout << "high is member" << endl;
}else
{
cout << "high is not member" << endl;
}
cout << "********删除成员(removeMember)**********" << endl;
value_read.removeMember("sex");
string str3=style_writer.write(value_read);
cout << "str3" << str3 << endl;
return 0;
}
编译语句如下:
g++ jsontest.cpp -I /jsoncpp/jsoncpp-src-0.5.0/include -L /jsoncpp/jsoncpp-src-0.5.0/libs/linux-gcc-4.8.5/ -ljson_linux-gcc-4.8.5_libmt
随便创建一个test.txt文件放在当前目录。例如:
1111
2222
3333
编译完成后,执行./a.out 即可看到运行效果。
(1)如下图所示即为无格式输出和有格式输出的区别:
举例三——json的数组读写
#include
#include
#include
using namespace std;
int main()
{
//std::string strValue = "{\"name\":\"json\",\"array\":[{\"cpp\":\"jsoncpp\"},{\"java\":\"jsoninjava\"},{\"php\":\"support\"}]}";
// 构建json数组
Json::Value root;
Json::Value group;
Json::Value person;
Json::FastWriter writer;
person["name"] = "allen";
person["age"] = 10;
person["sex"] = "male";
group.append(person);
person["name"] = "keiv";
person["age"] = 20;
person["sex"] = "female";
group.append(person);
person["name"] = "lihua";
person["age"] = 10;
person["sex"] = "female";
group.append(person);
string strValue0 = group.toStyledString();
cout << "group Styled output is:" << endl;
cout << strValue0 << endl;
string data = writer.write(group);
cout << "group unStyled output is:" << endl;
cout << data << endl;
//给数组的第一个元素对应的json追加一个字段
if (group.size() > 0){
group[0]["unique_id"] = "unique_id";
}
//子节点挂到根节点上
root["array"] = Json::Value(group);
//cout<
6.json原始字串书写形式
json的规则其实很简单,我们完全可以按照规则书写出这些json串(看我们部门的代码其实也有很多生拼json的写法),而且书写出来的这些json字符串实际上也可以使用Json::Reader reader的parse方法解析成Json::Value对象被正常的按照json形式来引用操作的。一下给出几个例子:
#json对象包含在字符‘{’和‘}’中每个键值对由逗号分隔(最简单的例子):
{"age":26,"high":181,"name":"shuozhuo"}
#包含嵌套的例子
{"age":26,"high":181,"name":"shuozhuo","other_info":{"family":{"address":"anhui","number":4},"occupation":{"company_address":"shanghai","company_name":"tencent","occupation":"engineer"}}}
#array数组,JSON数据包含在字符‘[’和‘]’中,为一个由逗号分隔的值列表:
["apple","banana","orange","watermelon"]
{"id": 1, "age": 18, "name": "张三", "sister": [{"age": 30, "name": "张大姐"}, {"age": 20, "name": "张二姐"}]}
#数组嵌套的例子
{"id": 3, "age": 18, "name": "小明", "sister": [{"age": 25, "name": "小明大姐", "friend": [{"age": 25, "name": "大姐朋友一"}, {"age": 25, "name": "大姐朋友二"}]}, {"age": 20, "name": "小明二姐", "friend": [{"age": 22, "name": "二姐朋友一"}, {"age": 21, "name": "二姐朋友二"}]}]}
7.关于生拼json
很简单,一句话:除了最外层的双引号里面的每个双引号都加一个转义反斜线就好了。
如果出现变量的话也差不多就是对着上面生拼的字符串照搬过来然后用stringstream黏在一起就好了。实例如下:
#看看几个生拼json的实例,很简单。
"{\"id\":1,\"name\":\"kurama\"}"
"{\"menuid\":\"")+ m_msg.m_content+"\",\"menuname\":\""+m_msg.m_menuname+"\"}")
"{\"id\": 1, \"name\": \"张三\", \"age\": 18, \"sister\": [{\"name\": \"张大姐\", \"age\": 30}, {\"name\": \"张二姐\", \"age\": 20}]}"
"{ \"weatherinfo\":{\"city\":\"北京\", \"cityid\" : \"101010100\", \"temp\" : \"18\", \"WD\" : \"东南风\", \"WS\" : \"1级\", \"SD\" : \"17 % \", \"WSE\" : \"1\", \"time\" : \"17:05\", \"isRadar\" : \"1\", \"Radar\" : \"JC_RADAR_AZ9010_JB\", \"njd\" : \"这是什么\", \"qy\" : \"1011\", \"rain\" : \"0\"} }"
#include "json/json.h"
#include
#include
#include
using namespace std;
int main()
{
/*
这种生拼json没有任何问题。方法也说过了就是除了最外层引号外,其他所有的引号都加一个转义字符
*/
string test = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
string raw_payload = "{\"appId\":1255566655,\"fileId\":\"4564972818519602447\",\"currentTimeStamp\":1546340400,\"expireTimeStamp\":1546344000,\"urlAccessInfo\":{\"t\":\"5c2b5640\",\"rlimit\":3,\"us\":\"72d4cd1101\"}}";
cout << "test:" << test << endl;
cout << "raw_payload:" << raw_payload << endl;
Json::Reader reader;
Json::Value value;
/*
如果json中的value为变量该怎么办呢?——显然也是可以的。实例如下:
其实就是对着上面test的生拼字符串照搬过来用stringstream黏在一起就好了。
*/
string alg = "HS256";
string type = "JWT";
std::stringstream ss0;
ss0 << "{\"alg\":\"" << alg << "\",\"typ\":\"" << type << "\"}";
cout << "ssss:"<< ss0.str() << endl;
unsigned long long appid = 1255566655;
string fileid = "4564972818519602447";
unsigned long long currentStamp = 1546340400;
unsigned long long expireTimeStamp = 1546344000;
string t = "5c2b5640";
int rlimit = 3;
string us = "72d4cd1101";
std::stringstream ss;
ss << "{\"appId\":" << appid << ",\"fileId\":\"" << fileid << "\",\"currentTimeStamp\":" << currentStamp << ",\"expireTimeStamp\":" << expireTimeStamp << ",\"urlAccessInfo\":{\"t\":\"" << t << "\",\"rlimit\":" << rlimit << ",\"us\":\"" << us << "\"}}";
cout << "raw_payload:" << ss.str() << endl;
if(reader.parse(ss.str(),value))
{
cout << "value:" << value.toStyledString()<< endl;
}
return 0;
}
8.Json系统类型及常用成员函数
注:如下的好多方法必须要高版本jsoncpp才支持,例如“(Json::Value::UInt64)”、“(Json::Value::Int64)”这种; jsoncpp-src-0.5.0 不支持,jsoncpp-0.10.6支持。
注:“Int64 asInt64() const”的意思是我们取json某字段数值的时候可以使用 asInt64();同时也意味着“Int64”是jsoncpp认可的数据类型,即在给json赋值的时候可以用(Json::Value::Int64)来强制转换成jsoncpp认可的int64数据。如下:
下面这些方法,尤其是isXXX方法的实际效果见 这里
//类型转换
string asString() const; //是string才可以用asString来取(不可以对子json用asString)
Int asInt() const; //是数字才可以用asXXIntXX来取(返回类型Json::Value::Int)(当实际转换数据超过Int表示范畴就会core)
UInt asUInt() const; //是数字才可以用asXXIntXX来取(返回类型Json::Value::UInt)
Int64 asInt64() const; //是数字才可以用asXXIntXX来取;也可以强制转换为Int64类型(返回类型Json::Value::Int64)
UInt64 asUInt64() const; //是数字才可以用asXXIntXX来取;也可以强制转换为UInt64类型(返回类型Json::Value::UInt64)
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
// 检测类型的几个方法
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const; //浮点数、数字为true
bool isString() const; //字符串
bool isArray() const; //是否是数组
bool isObject() const; //是否对象(子结构为true)
//json的value.type()方法取值枚举(注释是源码摘出来的)
//Type of the value held by a Value object.
Json::nullValue //'null' value
Json::intValue //signed integer value
Json::uintValue //unsigned integer value
Json::realValue //double value
Json::stringValue //UTF-8 string value
Json::booleanValue //bool value
Json::arrayValue //array value (ordered list)
Json::objectValue //object value (collection of name/value pairs).
判断方法如下:
if (jsondata.type() == Json::objectValue)
{
cout << endl;
print_json(jsondata);
}
注:asInt、asUInt当待转换数据超过int、uint的标识范畴时就会core!!!
另外(注:其实这些就是上面列出来的检测类型的若干方法)。
(1)判断某个key(or子结构)是否存在使用isMember(判断key是否存在不能用empty);
(2)判断value是否为null:isNull成员函数;
(3)判断value是否为空:empty() 和 size()成员函数;
(4)判断value是否为数组:isArray();
(5)判断value是否为一个子结构:isObject()。
上面的isXxx方法都是可以用的这里就不继续列出来了…………
另外还可以通过type()方法取其类型做判断。
#如下,判断type是否为Json::objectValue也是可以的
if (person.type() == Json::objectValue)
{
cout << endl;
print_json(person);
}
9.上下文中出现的诸多方法都可以在源码中找到
/jsoncpp-0.10.6/include/json/value.h
10、jsoncpp遍历json数据
#include "json/json.h"
#include
#include
typedef Json::Writer JsonWriter;
typedef Json::Reader JsonReader;
typedef Json::Value JsonValue;
using namespace std;
void print_json(JsonValue data);
int main()
{
//string testJson = "{\"id\":1,\"name\":\"kurama\"}";
/*------------------------------------------
这里面涉及到json数组和json对象的区别(json数组是不可以调用getMemberNames方法的):
json数组:是由[]括起来的,中间可以包括json对象或者键值对;
json对象是由{}括起来的,中间可以报错接送对象或者键值对;
------------------------------------------*/
//string testJson = "{[{\"age\":10,\"name\":\"allen\",\"sex\":\"male\"},{\"age\":20,\"name\":\"keiv\",\"sex\":\"female\"},{\"age\":10,\"name\":\"lihua\",\"sex\":\"female\"}]}";
string testJson = "{ \"weatherinfo\":{\"city\":\"北京\", \"cityid\" : \"101010100\", \"temp\" : \"18\", \"WD\" : \"东南风\", \"WS\" : \"1级\", \"SD\" : \"17 % \", \"WSE\" : \"1\", \"time\" : \"17:05\", \"isRadar\" : \"1\", \"Radar\" : \"JC_RADAR_AZ9010_JB\", \"njd\" : \"这是什么\", \"qy\" : \"1011\", \"rain\" : \"0\"} }";
//解析json数据
JsonReader reader;
JsonValue value;
if (!reader.parse(testJson, value))
{
cout << value.toStyledString() << endl;
return 0;
}
//遍历键值
print_json(value);
system("pause");
return 0;
}
void print_json(JsonValue data)
{
/*---------Return a list of the member names--------*/
//getMemberNames仅对type为objectValue(json对象)或者nullValue(null)可用.
JsonValue::Members mem = data.getMemberNames();
for (auto iter = mem.begin(); iter != mem.end(); iter++)
{
cout << *iter << "\t: ";
if (data[*iter].type() == Json::objectValue)
{
cout << endl;
print_json(data[*iter]);
}
else if (data[*iter].type() == Json::arrayValue)
{
cout << endl;
auto cnt = data[*iter].size();
for (auto i = 0; i < cnt; i++)
{
print_json(data[*iter][i]);
}
}
else if (data[*iter].type() == Json::stringValue)
{
cout << data[*iter].asString() << endl;
}
else if (data[*iter].type() == Json::realValue)
{
cout << data[*iter].asDouble() << endl;
}
else if (data[*iter].type() == Json::uintValue)
{
cout << data[*iter].asUInt() << endl;
}
else
{
cout << data[*iter].asInt() << endl;
}
}
return;
}
注意:给属性字段赋值的时候可以赋字符串string、数字、布尔值、数组都是可以的。
低版本的jsoncpp不支持uint64(例如0.5.0就不支持C++中的long long)类型的数据!!!
(1)对于常值和非uint64(C++中的long long)的数值变量是可以直接赋值的,例如:
person["age"] = 26;
int high=181;
person["high"] = high;
(2)但是将int64/uint64用来赋值的时候就会报错,如下。
long long high = 181;
person["high"] = high;//这句在编译的时候会报错
/*----高版本的jsoncpp是支持int64/uint64;使用(Json::Value::UInt64)强制转换即可------*/
//(Json::Value::UInt64)转换后json就支持int64和uint64了(注意UInt64、Int64需要高版本的jsoncpp)。
jsonS2cContext["kfext"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_bqquin();
jsonS2cContext["cqq"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_cqquin();
//直接赋值的话会报错
jsonS2cContext["kfext"] = recep_record_qq_kfuin.uint64_bqquin();
jsonS2cContext["cqq"] = recep_record_qq_kfuin.uint64_cqquin();
赋uint64(long long)后对应的报错如下:
(3)注意左右两者的区别,他们的设置方式和取值方式都是不一样的。
//(1)前者是这样赋出来的:
jsonS2cContext["kfext"] = to_string(recep_record_qq_kfuin.uint64_bqquin());
jsonS2cContext["cqq"] = to_string(recep_record_qq_kfuin.uint64_cqquin());
//(2)后者是这样赋出来的:
//此处的(Json::Value::UInt64)仅仅是为了让json支持uint64的一种实现。
jsonS2cContext["kfext"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_bqquin();
jsonS2cContext["cqq"] = (Json::Value::UInt64)recep_record_qq_kfuin.uint64_cqquin();
//(3)下面这种不是uint64的数据用来直接赋值是没有任何问题的。
int age=26,weight=125;
person["age"] = age;
person["weight"] = weight;
//(4)对于前者取值方式如下:
//值得注意的是如果按照下方的asUInt或者asUInt64的方式来取值是会出错的。这个在编译的时候并没有报错,是那种执行到这条语句后直接戛然而止看不到任何报错信息的出错。
uint32_t channel = jsonS2cContext["channel"].asString();
uint64_t kfext = jsonS2cContext["kfext"].asString();
//(5)对于后者取值方式为:
uint32_t channel = jsonS2cContext["channel"].asUInt();
uint64_t kfext = jsonS2cContext["kfext"].asUInt64();
参见:
linux下jsoncpp的编译安装使用_elainedou_新浪博客
Linux下编译安装Jsoncpp及简单应用_Linux教程_Linux公社-Linux系统门户网站
11、json对二进制数据的支持情况。
背景:想用json的"msg_body"字段传输pb对象,显然pb对象是序列化之后的。
json+二进制(流/文件/数据)就往base64这块想想!!!!!
//如下是可以成功反解出pb对象的
data["msg_body"] = msg_info.SerializeAsString();
string str_msg_info = data["msg_body"].asString();
LOGSYS_WATER(_LC_DEBUG_, "size=%d, str_msg_info=%s", str_msg_info.size(), str_msg_info.c_str());
if (msg_info1.ParseFromString(str_msg_info)) {
LOGSYS_WATER(_LC_DEBUG_, "msg_info1=\n%s\n", msg_info1.DebugString().c_str());
}
else{
LOGSYS_WATER(_LC_ERROR_, "parse msg_info1 error!");
}
//即使json经过了序列化操作也还依然可以解出其中的pb对象
row["document"] = data;
str_row = writer.write(row);
Json::Reader reader;
Json::Value doc;
if (!str_row.empty() && reader.parse(str_row, doc)){
LOGSYS_WATER(_LC_DEBUG_, "doc is: \n%s", doc.toStyledString().c_str());
}
else{
LOGSYS_WATER(_LC_ERROR_, "parse str_row fail:\n%s", str_row.c_str());
}
string str_msg_info = doc["document"]["msg_body"].asString();
LOGSYS_WATER(_LC_DEBUG_, "str_msg_info=%s", str_msg_info.c_str());
com::tencent::qidian::cloudim::MsgInfo msg_info00;
if (msg_info00.ParseFromString(str_msg_info)) {
LOGSYS_WATER(_LC_DEBUG_, "msg_info00=\n%s\n", msg_info00.DebugString().c_str());
}
else{
LOGSYS_WATER(_LC_ERROR_, "parse msg_info00 error!");
}
//但是直接这样把数据存储到db中,然后在取出来又确实不行。!!
//究竟是哪个环节不行的呢?难道经过网络传输后就不行了吗???
附录——源码之value.h:
// Copyright 2007-2010 Baptiste Lepilleur
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef CPPTL_JSON_H_INCLUDED
#define CPPTL_JSON_H_INCLUDED
#if !defined(JSON_IS_AMALGAMATION)
#include "forwards.h"
#endif // if !defined(JSON_IS_AMALGAMATION)
#include
#include
#include
#ifndef JSON_USE_CPPTL_SMALLMAP
#include