`
agapple
  • 浏览: 1582902 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

hessian序列化源码分析

    博客分类:
  • java
阅读更多

  1. 背景

    最近在处理一个hessian的反序列化问题时,因为服务端使用了pojo bean中多了一个enum属性,导致客户端在反序列化时疯狂的在打印日志。警告说找不到对应的enum class,因为项目中本身是设置了log4j的根输出为一个文件。 

    比较奇怪的是,hessian对应的日志输出全都打印到了控制台(虽然我们对console进行了重定向输出),导致对应的文件达到几百MB。无奈之下,仔细分析了下hessian的源码。

介绍

 

先看一张hessian主要的几个概念图

说明:

 

  1. Serializer  序列化的接口
  2. Deserializer 反序列化的接口
  3. AbstractHessianInput  hessian自定义的输入流,提供对应的read各种类型的方法
  4. AbstractHessianOutput  hessian自定义的输出流,提供对应的write各种类型的方法

 

AbstractSerializerFactory介绍

serializerFactory从字面意思上也看的出来,是管理和维护对应序列化/反序列化机制的工厂。默认的几种实现

 

  • SerializerFactory 标准的实现
  • ExtSerializerFactory 我们可以设置自定义的序列化机制,通过该Factory可以进行扩展。
  • BeanSerializerFactory 对SerializerFactory的默认object的序列化机制进行强制指定,指定为BeanSerializer。 具体BeanSerializer的实现后面再表。
自定义序列化机制的扩展:
  1. 实现Serializer/Deserializer接口
  2. ExtSerializerFactory extSerializerFactory = new ExtSerializerFactory();
    extSerializerFactory.addSerializer(class , mySerializer); //添加自定义的序列化接口
    extSerializerFactory.addDeserializer(class , myDeserializer); //添加自定义的反序列化接口
    
    serializerFactory.addFactory(extSerializerFactory); //注册ext到序列化工厂
     

 

SerializerFactory介绍:
先看一下hesian提供的Serializer/Derializer几种默认实现

 







具体的实现就不细说,有兴趣的自己看代码去。
下面提一下我在看得过程中比较在意和疑惑过的点。

1.  Object对象的序列化/反序列化
答:JavaSerializer或者BeanSerializer。这两者的区别

 

  • JavaSerializer是通过反射获取所有bean的属性进行序列化,排除static和transient属性,对其他所有的属性进行递归序列化处理(比如属性本身是个对象)。
  • BeanSerializer是遵循pojo bean的约定,扫描bean的所有方法,发现存在get和set方法的属性进行序列化,它并不直接直接操作所有的属性,比较温柔。 注意:BeanSerializer将会无法处理你的boolean属性,因为通过默认的eclipse生成的方法是以isXXX打头,不会被序列化。
2.  枚举对象的序列化/反序列化
答:看过类图后,就很明显的发现存在一个EnumSerializer和EnumDeserializer实现。大家都知道枚举对象全都继承于enum对象,所以EnumSerializer会反射调用name方法,EnumDeserializer是反射调用valueof方法。这样就很明显了,如果服务端多了一个枚举值定义,客户端反序列化会出现异常,不会是一个兼容的过程。

 

补充:测试过程中,hessian 3.1.3版本存在enum序列化问题,低级的问题。

 
3.  服务端抛异常后的序列化/反序列化
答:这个也是在做rpc调用,一个比较容易被遗忘的点,只关注了正常的业务功能的流程,却没有考虑对应的异常处理的序列化和反序列化。hessian提供了ThrowableSerializer和StackTraceElementDeserializer进行序列化处理。
  • ThrowableSerializer会按照object的序列化方式,传递对应的信息到客户端。包括stackTrace和detailMessage等。
  • StackTraceElementDeserializer反序列化对应的异常栈信息。异常的其他属性通过JavaSerializer进行反序列化处理。
补充:测试过程中,hessian 3.0.20,3.1.3版本存在问题,异常的反序列化在hessian 1.0协议是正常的,到2.0就会出现错误。 具体的问题也有人报告了bug : http://maillist.caucho.com/pipermail/hessian-interest/2008-February/000297.html ,升级到3.1.5之后就解决了.

测试代码


    public static void exceptionTest() throws Exception {
        Exception exception = null;
        try {
            FileInputStream stream = new FileInputStream("notfound");
        } catch (FileNotFoundException e) {
            exception = e;
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        HessianOutput out = new HessianOutput(bos);
        out.writeObject(exception);
        out.flush();

        byte[] bytes = bos.toByteArray();
        ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
        HessianInput in = new HessianInput(bin);
        Exception read = (Exception) in.readObject(FileNotFoundException.class);
        read.printStackTrace();
        System.out.println(read);
    }
 
hessian支持对流进行压缩处理,可以看下 Deflation
Hessian2Output out = new Hessian2Output(bos);
out = envelope.wrap(out); //包装为压缩

Hessian2Input in = new Hessian2Input(bin);
in = envelope.unwrap(in); //解缩
 
压缩慎用,在测试过程中有一些磕磕碰碰的小问题。 

后记

hessian序列化机制的性能比较,后续补上。 主要是和原先的几种序列化协议相关数据对比

 

序列化数据对比


bytes字节数对比


具体的数字: 

  protobuf jackson xstream Serializable hessian2 hessian2压缩 hessian1
序列化(单位ns) 1154 5421  92406  10189 26794 100766 29027
反序列化(单位ns) 1334 8743  117329  64027 37871 188432 37596
bytes 97 311  664  824 374 283 495

 

 

  • 大小: 15.5 KB
  • 大小: 16.3 KB
  • 大小: 16.6 KB
  • 大小: 11.4 KB
  • 大小: 13.8 KB
6
4
分享到:
评论
1 楼 java_林 2013-08-01  
hessian4.0.7中
BeanSerializerFactoryx继承SerializerFactory

相关推荐

    JAVA上百实例源码以及开源项目源代码

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    JAVA上百实例源码以及开源项目

     Java生成密钥、保存密钥的实例源码,通过本源码可以了解到Java如何产生单钥加密的密钥(myKey)、产生双钥的密钥对(keyPair)、如何保存公钥的字节数组、保存私钥到文件privateKey.dat、如何用Java对象序列化保存私钥...

    java开源包8

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    【JeeSpringCloud v3.2.4】后台权限管理系统+互联网云快速开发框架+微服务分布式代码生成

    另外,REST调用也达到了比较高的性能,在基准测试下,HTTP + JSON默认的RPC协议(即TCP + Hessian2二进制序列化)之间只有1.5倍左右的差距,详见下文的基准测试报告。 ORM/Redis/Service仓库 RepositoryORM仓库,...

    java开源包1

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包11

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包2

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包3

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包6

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包5

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包10

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包4

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包7

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包9

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    java开源包101

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

    Java资源包01

    6、支持多种通信框架(Mina/Netty/Grizzly),支持多种序列化/反序列化(Java/Hessian/PB); 7、支持自定义通信协议,可完全替换NFS-RPC自带的协议。 淘宝开放平台JAVA版SDK top4java 设计原则 容易维护扩展(不...

Global site tag (gtag.js) - Google Analytics