`
DiaoCow
  • 浏览: 244318 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Hessian源码学习(三)序列化概述

阅读更多
今天我们重点来看看Hessian是如何实现序列化的(这些序列化类可以脱离hessian源码包,单独拿出来使用),参考源码版本为3.0.13

首先我们看下序列化一个对象的代码:
// 这里可以是任何形式的OutputStream,现以FileOutputStream为例
OutputStream os = new FileOutputStream("hessianOutput"); 
// 创建 HessianOutput对象
AbstractHessianOutput out = new HessianOutput(os); 
// 设置序列化工厂(其实上一步初始化已经默认带你设置了SerializerFactory)
out.setSerializerFactory(new SerializerFactory()); 
// 序列化 obj对象(obj可以是一个简单对象比如Integer,String,数组,枚举,集合也可以是一个自定义类)
 out.writeObject(new Integer(10)); 

我们看一下序列化后的结果:



现在我们来逐步分析下上面这段代码:

1.out.setSerializerFactory(new SerializerFactory());

首先SerializerFactory是什么?顾名思义 SerializerFactory是一个序列化工厂,里面包含了序列化(反序列化)各种对象的Serializer(DeSerializer)类,我们看下在创建SerializerFactory时,它做了写什么:(为了表达方面的方便,我这里只说序列化)
// 静态代码快(初始化SerializerFactory)
static {

     // 创建序列化和反序列化map,至于其中的Key-Value 我想大家也能猜到,key就是某个需要序列化的class,value就是序列化该class 对应的Serializer类

    _serializerMap = new HashMap();
    _deserializerMap = new HashMap();
    _typeMap = new HashMap();

     // 初始化序列化和反序列化map (对于“简单类型”都使用BasicSerializer作为它的序列化类)
    addBasic(void.class, "void", BasicSerializer.NULL); //基本类型
    addBasic(Boolean.class, "boolean", BasicSerializer.BOOLEAN);
    addBasic(Byte.class, "byte", BasicSerializer.BYTE);
    // 省略类似代码...

    addBasic(boolean.class, "boolean", BasicSerializer.BOOLEAN); //基本对象类型
    addBasic(byte.class, "byte", BasicSerializer.BYTE);
    // 省略类似代码...
    
    addBasic(boolean[].class, "[boolean", BasicSerializer.BOOLEAN_ARRAY); //基本数组类型
    addBasic(byte[].class, "[byte", BasicSerializer.BYTE_ARRAY);
    addBasic(short[].class, "[short", BasicSerializer.SHORT_ARRAY);
    // 省略类似代码...

    _serializerMap.put(Class.class, new ClassSerializer());
    _deserializerMap.put(Class.class, new ClassDeserializer());

    _deserializerMap.put(Number.class, new BasicDeserializer(BasicSerializer.NUMBER));
    
    _serializerMap.put(BigDecimal.class, new StringValueSerializer());
    try {
      _deserializerMap.put(BigDecimal.class,
			   new StringValueDeserializer(BigDecimal.class));
    } catch (Throwable e) {
    }
    
    // 后面代码省略,内容基本同上
}

上面代码中 addBasic()方法做了写什么呢?

addBasic()做的很简单,以addBasic(Integer.class, "int",BasicSerializer.INTEGER)为例子:

实际上就是_serializerMap.put(Integer.class, new BasicSerializer(BasicSerializer.INTEGER));
private static void addBasic(Class cl, String typeName, int type)
{
	// 放入key-value
	_serializerMap.put(cl, new BasicSerializer(type));

	Deserializer deserializer = new BasicDeserializer(type);
	_deserializerMap.put(cl, deserializer);
	_typeMap.put(typeName, deserializer);
}

2.out.writeObject(obj);

HessianOutput 继承 AbstractHessianOutput 且 writeObject是 父类中的一个抽象方法,我们看下在HessianOutput中 writeObject做了写什么:
public void writeObject(Object object)
    throws IOException
{
	if (object == null) {
	  writeNull();
	  return;
	}

	Serializer serializer;
	//从序列化工厂得到能够序列化该对象的序列化类
	serializer = _serializerFactory.getSerializer(object.getClass());   
	//使用具体的序列化类序列化对象
	serializer.writeObject(object, this); 
}

我们看下 _serializerFactory.getSerializer(object.getClass());的实现
public Serializer getSerializer(Class cl)
    throws HessianProtocolException
{
    Serializer serializer;

	// 如果是简单类型,那么直接就能获取到(备注:这里能够取到的都是之前在SerializerFactory的static静态代码块中初始化的那些key)
    serializer = (Serializer) _serializerMap.get(cl);
    if (serializer != null)
      return serializer;

	// 从缓存中取 (为什么这里有个缓存的东西,看后面代码就立刻明了)
    if (_cachedSerializerMap != null) {
      serializer = (Serializer) _cachedSerializerMap.get(cl);
      
      if (serializer != null)
	return serializer;
    }
	
	// 省略部分代码....

	// 获取其他类型的序列化类
    if (serializer != null) {
    }

    else if (HessianRemoteObject.class.isAssignableFrom(cl))
      serializer = new RemoteSerializer();

    else if (BurlapRemoteObject.class.isAssignableFrom(cl))
      serializer = new RemoteSerializer();

    else if (Map.class.isAssignableFrom(cl))
      serializer = new MapSerializer();
    // 省略部分相似代码....
   

  // 如果以上都未能找到合适的序列化类,则使用默认序列化类(JavaSerializer,通常序列化我们自定义类的就是它),
    if (serializer == null)
	 
      serializer = getDefaultSerializer(cl);  

	
    if (_cachedSerializerMap == null)
      _cachedSerializerMap = new HashMap(8);

	
	// 放入缓存map中,下次获取同样的序列化类就比较方便,不需要再经过那么多判断了
    _cachedSerializerMap.put(cl, serializer);

    return serializer;
}

3.serializer.writeObject(object, this);

这里使用刚才获取到的Serializer类(可能是JavaSerializer,也可能是BasicSerializer或者其他序列化类)来序列化对象,具体实现留待下次分析

总结一下序列化的过程就是:



总结

1.如何使用Hessian序列化对象;

2.Hessian序列化对象分哪几步,每一步的大概含义是什么?

3.SerializerFactory是什么,它默认做了哪些工作?

下一节,我们将深入各个序列化类的具体实现,欢迎朋友指正!
  • 大小: 57.7 KB
  • 大小: 57.6 KB
  • 大小: 15 KB
3
2
分享到:
评论

相关推荐

    hessian学习基础篇——序列化和反序列化

    通过阅读和分析Hessian的源码,我们可以了解其如何编码和解码各种数据类型,以及如何优化序列化和反序列化的过程。这对于优化自定义序列化逻辑或者解决Hessian使用中遇到的问题非常有帮助。 总结起来,Hessian是一...

    Hessian 的字段序列化小记

    - 分析Hessian的源码可以帮助我们理解其内部实现,比如如何优化序列化过程,如何处理异常情况,以及如何实现类型兼容性等。这对于我们自定义序列化逻辑或优化现有应用的性能都非常有价值。 5. **应用场景** - 在...

    S25-hessian反序列化1

    【S25-Hessian反序列化1】是一个关于Java中Hessian序列化库的讨论,主要涉及Hessian与原生Java序列化的差异以及在Spring框架中的应用。Hessian是一种二进制序列化协议,旨在提高远程过程调用(RPC)的效率。与原生Java...

    hessian序列化规范

    三、Hessian序列化特性 1. **效率高**:Hessian采用二进制格式,比XML和JSON等文本格式在网络传输上更节省带宽,提高了传输速度。 2. **跨平台**:Hessian协议是跨语言的,可以用于Java、C++、Python等多种语言间...

    Hessian 2.0序列化协议规范.docx

    《Hessian 2.0序列化协议规范》 在分布式计算和网络通信中,数据的序列化和反序列化是至关重要的环节。Hessian 2.0是一种高效的二进制序列化协议,它旨在减少网络传输的数据量,提高数据交换的效率。本文将详细介绍...

    浅谈Java序列化和hessian序列化的差异

    Java序列化和Hessian序列化的差异 Java序列化和Hessian序列化是两种常用的序列化机制,它们都可以将对象转换为字节流,以便在网络上传输。但是,两者之间有着很大的差异,今天我们就来比较一下它们的实现机制和特点...

    Nacos JRaft Hessian 反序列化 RCE 分析.pdf

    ### Nacos JRaft Hessian 反序列化 RCE 分析 #### 一、背景介绍 Nacos 是阿里巴巴开源的一款易于构建云原生应用的动态服务发现、配置管理和服务管理平台。JRafT 是 SOFAStack 微服务平台中的一个分布式一致性组件...

    hessian源码修改,包含了协议的修改

    公司搞soa治理,正好采用hessian的export暴露接口,我修改了下,客户端不需要采用url,直接采用servicename,从zookeeper取地址列表。客户端和服务端通过mina通讯,不采用原生的http协议。目前mina的编码解码还有待...

    Hessian学习简单demo

    Hessian的目标是提供一种快速、简洁的数据序列化和远程方法调用(RPC)机制。在这个简单的demo中,我们将探讨Hessian的核心概念,以及如何在实际应用中使用它。 首先,我们需要理解什么是数据序列化。数据序列化是...

    Hessian多个版本打包下载

    Hessian是一种高效的二进制序列化协议,常用于远程过程调用(RPC)和服务之间的通信。这个压缩包包含了Hessian的多个版本,分别是Hessian3.1.6、Hessian3.2.1以及Hessian4.0.7。每个版本都有其特定的功能改进和优化...

    Hessian 学习 例子 实例

    在IT行业中,Hessian是一种二进制序列化协议,它被广泛用于远程方法调用(RMI)和Web服务中,以提高数据传输效率。Hessian由Caucho Technology开发,其目标是提供轻量级、高效的通信方式,特别是在网络带宽有限的...

    Hessian-4.0.7(Jar包 + 源码)

    通过阅读源码,开发者可以了解Hessian如何实现高效的序列化和反序列化,以及它是如何处理网络通信的。源码也使得开发者能够根据需要修改或扩展Hessian的功能,例如添加新的序列化策略,或者优化特定场景下的性能。 ...

    Hessian

    Caucho Technology提供了Hessian的开源实现,开发者可以通过阅读源码了解其内部细节,如序列化和反序列化的具体实现、类型转换逻辑等。 在博客链接《iteye博客:550771》中,作者可能详细讨论了Hessian的使用方法、...

    Hessian源码示例

    Hessian是一种二进制协议,它用于远程方法调用(RPC)和序列化。这个"**Hessian源码示例**"很可能包含了使用HessianCSharp库在C#环境中实现服务端和客户端通信的示例代码。HessianCSharp是.NET平台上的一个开源库,...

    Hessian学习笔记

    综上所述,学习Hessian需要掌握二进制序列化技术,理解远程方法调用的概念,熟悉Hessian的实现和使用,并关注安全性、性能优化等方面的问题。同时,通过阅读源码和实践项目,可以更深入地理解这个协议的精髓。

    removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)

    removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)

    Hessian应用

    这样,客户端通过网络发送一个Hessian序列化的请求,服务端接收后反序列化为本地对象,然后执行相应的操作,再序列化结果返回给客户端。 在实际应用中,Hessian主要应用于以下场景: 1. **分布式服务调用**:通过...

    Hessian的学习笔记

    2. Hessian将请求信息进行序列化,产生二进制流。 3. Hessian基于Http协议将二进制流传输至服务端。 4. 服务端根据Hessian提供的API接收请求,处理请求并返回结果。 5. Hessian将结果对象进行序列化,传输至客户端。...

Global site tag (gtag.js) - Google Analytics