浅析若干Java序列化工具【转】
2016-06-08 10:41
429 查看
在Java中socket传输数据时,数据类型往往比较难选择。可能要考虑带宽、跨语言、版本的兼容等问题。比较常见的做法有:
采用java对象的序列化和反序列化
把对象包装成JSON字符串传输
Google工具protoBuf的开源
为了便于说明各个做法的区别,分别对这三种做法进行阐述。 对UserVo对象进行序列化,class UserVo如下:
初始化一个UserVo实例:
序列化大小:205.
优点:java原生支持,不需要提供第三方的类库,使用比较简单。缺点:无法跨语言,字节数占用比较大,某些情况下对于对象属性的变化比较敏感。
序列化大小:111.
注意到这里Jackson会输出null,在Jackson的2.x版本中可以通过设置而使其不输出null的字段。
序列化大小:81.
Gson和Jackson的区别是:如果你的应用经常会处理大的JSON文件,那么Jackson应该是你的菜。GSON在大文件上表现得相当吃力。如果你主要是处理小文件请求,比如某个微服务或者分布式架构的初始化,那么GSON当是首选。Jackson在小文件上的表现则不如人意。
FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
注:如果只是功能要求,没有性能要求,可以使用google的Gson,如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean。
protoBuf优点:1.性能好,效率高;2.代码生成机制,数据解析类自动生成;3.支持向前兼容和向后兼容;4.支持多种编程语言;5.字节数很小,适合网络传输节省io。缺点:1.应用不够广;2.二进制格式导致可读性差;3.缺乏自描述;
protoBuf是需要编译工具的,这里用的是window的系统。需要下载proto.exe和protobuf-java-2.4.1.jar;
将proto.exe放在当前工程目录下,然后编辑.proto文件,命名为UserVo.proto,如下所示:
在命令行中利用protoc工具生成builder类:
看到生成了UserVoProtos.java,由于这个java文件有1千行左右,篇幅限制不便罗列。
序列化和反序列化测试代码:
序列化大小:23.
工作机制:proto文件是对数据的一个描述,包括字段名称,类型,字节中的位置。protoc工具读取proto文件生成对应builder代码的类库。protoc xxxxx –java_out=xxxxxx 生成java类库。builder类根据自己的算法把数据序列化成字节流,或者把字节流根据反射的原理反序列化成对象。官方的示例:https://developers.google.com/protocol-buffers/docs/javatutorial。proto文件中的字段类型和java中的对应关系:详见:https://developers.google.com/protocol-buffers/docs/proto.
注:protobuf的一个缺点是需要数据结构的预编译过程,首先要编写.proto格式的配置文件,再通过protobuf提供的工具生成各种语言响应的代码。由于java具有反射和动态代码生成的能力,这个预编译过程不是必须的,可以在代码执行时来实现。有个protostuff(http://code.google.com/p/protostuff/)已经实现了这个功能。protostuff基于Google protobuf,但是提供了更多的功能和更简易的用法。其中,protostuff-runtime实现了无需预编译对java bean进行protobuf序列化/反序列化的能力。protostuff-runtime的局限是序列化前需预先传入schema,反序列化不负责对象的创建只负责复制,因而必须提供默认构造函数。此外,protostuff还可以按照protobuf的配置序列化成json/yaml/xml等格式。这里不做详述,有兴趣的朋友可以参考相关资料。
总结:
采用java对象的序列化和反序列化
把对象包装成JSON字符串传输
Google工具protoBuf的开源
为了便于说明各个做法的区别,分别对这三种做法进行阐述。 对UserVo对象进行序列化,class UserVo如下:
采用java对象的序列化和反序列化
这里简单说明一下java序列化所占用字节大小,具体可以参考http://blog.csdn.net/u013256816/article/details/50474678。优点:java原生支持,不需要提供第三方的类库,使用比较简单。缺点:无法跨语言,字节数占用比较大,某些情况下对于对象属性的变化比较敏感。
把对象包装成JSON字符串传输
JSON工具类有许多种,这里列出三个比较流行的json工具类:Jackson,Gson,FastJson.1.开源的Jackson
Jackson社区相对比较活跃,更新速度也比较快。Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式。注意到这里Jackson会输出null,在Jackson的2.x版本中可以通过设置而使其不输出null的字段。
2. Google的Gson
Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,但自从在2008年五月公开发布第一版后已被许多公司或用户应用。Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。Gson在功能上面无可挑剔,但是性能上面比FastJson有所差距。Gson和Jackson的区别是:如果你的应用经常会处理大的JSON文件,那么Jackson应该是你的菜。GSON在大文件上表现得相当吃力。如果你主要是处理小文件请求,比如某个微服务或者分布式架构的初始化,那么GSON当是首选。Jackson在小文件上的表现则不如人意。
3. 阿里巴巴的FastJson
Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
注:如果只是功能要求,没有性能要求,可以使用google的Gson,如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean。
Google工具protoBuf
protocol buffers 是google内部得一种传输协议,目前项目已经开源。它定义了一种紧凑得可扩展得二进制协议格式,适合网络传输,并且针对多个语言有不同得版本可供选择。protoBuf优点:1.性能好,效率高;2.代码生成机制,数据解析类自动生成;3.支持向前兼容和向后兼容;4.支持多种编程语言;5.字节数很小,适合网络传输节省io。缺点:1.应用不够广;2.二进制格式导致可读性差;3.缺乏自描述;
protoBuf是需要编译工具的,这里用的是window的系统。需要下载proto.exe和protobuf-java-2.4.1.jar;
将proto.exe放在当前工程目录下,然后编辑.proto文件,命名为UserVo.proto,如下所示:
看到生成了UserVoProtos.java,由于这个java文件有1千行左右,篇幅限制不便罗列。
序列化和反序列化测试代码:
工作机制:proto文件是对数据的一个描述,包括字段名称,类型,字节中的位置。protoc工具读取proto文件生成对应builder代码的类库。protoc xxxxx –java_out=xxxxxx 生成java类库。builder类根据自己的算法把数据序列化成字节流,或者把字节流根据反射的原理反序列化成对象。官方的示例:https://developers.google.com/protocol-buffers/docs/javatutorial。proto文件中的字段类型和java中的对应关系:详见:https://developers.google.com/protocol-buffers/docs/proto.
.proto Type | java Type | c++ Type |
---|---|---|
double | double | double |
float | float | float |
int32 | int | int32 |
int64 | long | int64 |
uint32 | int | uint32 |
unint64 | long | uint64 |
sint32 | int | int32 |
sint64 | long | int64 |
fixed32 | int | uint32 |
fixed64 | long | uint64 |
sfixed32 | int | int32 |
sfixed64 | long | int64 |
bool | boolean | bool |
string | String | string |
bytes | byte | string |
注:protobuf的一个缺点是需要数据结构的预编译过程,首先要编写.proto格式的配置文件,再通过protobuf提供的工具生成各种语言响应的代码。由于java具有反射和动态代码生成的能力,这个预编译过程不是必须的,可以在代码执行时来实现。有个protostuff(http://code.google.com/p/protostuff/)已经实现了这个功能。protostuff基于Google protobuf,但是提供了更多的功能和更简易的用法。其中,protostuff-runtime实现了无需预编译对java bean进行protobuf序列化/反序列化的能力。protostuff-runtime的局限是序列化前需预先传入schema,反序列化不负责对象的创建只负责复制,因而必须提供默认构造函数。此外,protostuff还可以按照protobuf的配置序列化成json/yaml/xml等格式。这里不做详述,有兴趣的朋友可以参考相关资料。
总结:
方式 | 优点 | 缺点 |
---|---|---|
JSON | 跨语言、格式清晰一目了然 | 字节数比较大,需要第三方类库 |
Object Serialize | java原生方法不依赖外部类库 | 字节数大,不能跨语言 |
Google protobuf | 跨语言、字节数比较少 | 编写.proto配置用protoc工具生成对应的代码 |
相关文章推荐
- Java Web学习
- 自动生成代码工具【JAVA版】
- jdk源码分析之WeakHashMap
- Java - synchronized keyword
- SpringMVC form提交报错The request sent by the client was syntactically incorrect
- SpringMVC + Shiro 访问未授权页面时不跳转,页面打印抛异常
- 蚁群算法
- SpringMVC + Shiro通过注解配置的权限未生效
- Maven、eclipse与Nexus私服配置指南
- struts2的核心组件与流程
- Java的native方法
- spring4.x注解概述
- Java线程之由生产者/消费者问题看线程同步与通信
- 深入分析JavaWeb 49 -- Struts2中常用标签与主题
- struts2 hibernate搭建过程
- 详解堆排序算法原理及Java版的代码实现
- 随笔之javamail邮件发送(阿里云企业邮箱)
- java提高篇之详解内部类
- Java之静态内部类和非静态内部类的区别
- Spring 4.x官方参考文档中文版——第21章 Web MVC框架(11)