json是序列化与反序列化的一种方式。
1. 什么叫序列化和反序列化?用途是什么?
把对象转换为字节序列的过程称为对象的序列化。
把字节序列恢复为对象的过程称为对象的反序列化。
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
对象的序列化主要有两种用途:
在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方收到对象后则需要把字节序列再恢复为相应对象进行某些操作。
以上引用自: http://www.cnblogs.com/xdp-gacl/p/3777987.html 《Java基础学习总结——Java对象的序列化和反序列化》 <孤傲苍狼>
2. 如果不使用序列化,直接在发送端和接收端发送对象会产生什么问题?
假如发送端和接收端都使用c++编写,发送端给接收端发送一个结构体,对象如下:
struct args
{
long arg1;
long arg2;
}
args arg;
arg.arg1 = 1;
arg.arg2 = 2;
Writen(sockfd,&args,sizeof(args));
接收端代码为:
struct args arg;
Readn(sockfd,&arggs,sizeof(args))
这样写会有什么问题呢?其实以上代码存在三个潜在的问题:
(1)不同的实现以不同的格式存储二进制数。最常见的便是不同的字节序问题。有的机器使用大端字节序有的机器使用小端字节序。
(2)不同的实现在存储相同的C数据类型上可能存在差异。举例来说,大多数32位unix系统使用32位表示长整数,而64位系统却典型地使用64位来表示同样的数据类型。对于short、int或long等整数类型,它们各自的大小没有确定的保证。
(3)不同的实现给结构体打包的方式存在差异,取决于各种数据类型所用的位数以及机器的对齐限制。
因此,穿越套接字传送二进制结构绝不是明智的。
以上参考自《Unix网络编程卷1》的5.18节《数据格式》
解决这种数据格式问题的一个方法就是显示定义所支持数据类型的二进制格式(位数、大端或小端字节序),并以这种的格式在客户与服务器之间传送所有数据,而序列化统统帮我们做好了这些工作。
3. 常用的序列化与反序列化协议
当下比较流行的序列化协议,包括XML、JSON、Protobuf、Thrift和Avro。
具体参考:http://www.jb51.cc/article/p-cfncyyvg-nh.html 《序列化和反序列化》 <美团科技>
4. json介绍
为什么学习json?
因为 JSON 是 JavaScript 原生格式,这意味着使用json在web服务器和前端客户端通信时,用 JavaScript 中处理 JSON 数据不需要任何特殊的 API 或工具包。
json语法见http://www.json.org/json-zh.html
5. 使用json在web服务器和前端通信
例子见:http://www.jb51.cc/article/p-suisxcvg-et.html
6. jsconcpp
C++要使用JSON来解析数据,一般采用jsoncpp。
(1)linux下编译:
从https://github.com/open-source-parsers/jsoncpp 下载jsconcpp
解压,然后进入解压根目录
参考https://github.com/open-source-parsers/jsoncpp对jsoncpp对jsoncpp进行编译
mkdir -p build/debug cd build/debug cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=OFF -DARCHIVE_INSTALL_DIR=. -G "Unix Makefiles" ../.. make sudo make install
然后查看pkg-config/jsoncpp.pc.in,就可以看到jsoncpp的安装目录
(2)使用doxygen编译jsoncpp文档
python doxybuild.py --doxygen=$(which doxygen) --open --with-dot
如果doxygen安装在/usr/bin等环境变量path指定的目录下, --doxygen=$(which doxygen)
可以省掉
--with-dot
代表使用Graphviz的dot命令生成jsoncpp的函数调用图。所以编译文档之前需要安装Graphviz。centos运行sudo yum install graphviz
即可。
(3)使用方法:
jsoncpp编译为静态库libjsoncpp.a,放到/usr/local/bin,头文件在/usr/local/include/json/中
编程程序后,直接使用-ljsoncpp来链接libjsoncpp即可。
7. jsoncpp示例代码
示例代码:
http://www.cnblogs.com/kex1n/archive/2011/12/02/2272328.html 《jsoncpp的使用》 <小楼一夜听春雨>
http://www.jb51.cc/article/p-zuzukfda-bcr.html 《数据/配置 的存储方式 Json篇 以JsonCpp库使用为例》 <九天雁翎的博客> 其中第一篇文章已转载到自己的博客中。