<转>Hessian 序列化和反序列化实现
先聊聊 Java的序列化,Java官方的序列化和反序列化的实现被太多人吐槽,这得归于Java官方序列化实现的方式。
1、Java序列化的性能经常被吐槽。
2、Java官方的序列化后的数据相对于一些优秀的序列化的工具,还是要大不少,比如probuf,这大大影响存储和传输的效率。
3、Java序列化一定需要实现Serializable接口
4、Java序列化的 serialVersionUID 也是个大坑
另外,序列化和反序列化中还需要考虑:跨语言,新旧对象版本兼容,安全,性能。今天主要来说说,Hessian2是如何来解决这些问题的?
一、跨语言:hessian提供了一整套的byte[]的写入规范,这个规范为其他的语言实现hessian的序列化和反序列化提供了可能。
http://hessian.caucho.com/doc/hessian-serialization.html
目前hessian2已经支持了非常多语言,Java,Node,php,Erlang,c#.......
二、新旧对象版本兼容:hessian2将类的描述信息写入byte[]中,以便于在反序列化时候能正常。但是这样就带来了一个问题:序列化后的内容较大。
三、安全,hessian序列化时,会调用writeReplace方法得到一个新的对象,能将对象中的一些值进行加密后在进行序列化。
四、性能:hessian2的序列化在内容的序列化上做了一些优化,hessian2将需要序列化的多个相同的对象只会写入一次,其他用到该对象的只使用对象的引用,而不重新写入对象的描述信息和值信息。但是hessian2在描述信息上写入的信息来兼容动态化的反序列化支持,所以内容相对于一些描述性的序列化工具(thrift,protobuf)来说,在性能上没有优势。
再回到序列化,相对于 Java来说,hessian的序列化从跨语言,新旧对象的版本兼容,安全以及性能方面都做的好,主要体现在:
一、Java的序列化无法跨语言。
二、新旧对象的版本Java可以通过一个serialVersionUID来处理,这就需要开发者关注序列化的几个语义。
三、Java需要实现一个接口才能进行序列化和反序列化,序列化没有进行加解密的接口。
四、Java序列化后的内容比Hessian更大,这不利于序列化本身的性能和网络传输、以及存储的性能。
当然我们还有更加优秀的一些序列化和反序列化的工具,根据不同的使用场景可以自行选择!
对性能敏感,对开发体验要求不高的内部系统。
thrift/protobuf
对开发体验敏感,性能有要求的内外部系统。
hessian2
对序列化后的数据要求有良好的可读性
jackson/gson/xml