(七)数据序列化-hessian2

本文详细介绍了Hessian2协议的工作原理,包括如何进行对象的序列化和反序列化,以及在Dubbo中如何使用Netty进行消息收发。通过具体的Car对象示例,解析了序列化后的二进制内容,展示了对象属性嵌套对象属性的序列化形式。此外,还提供了自己实现的RPC框架的GitHub链接以供参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用hessian2协议,也就是传输对象序列化,它是二进制的RPC协议,与RMI不同的是,以标准的二进制格式定义请求的信息(请求的对象、方法、参数等),可以跨语言通讯,而RMI只局限于java间通讯。
1.hessian2原理

java-hessian2
自定义的类使用默认的序列化类com.caucho.hessian.io.JavaSerializer(Class, ClassLoader)

接口Serializer定义了序列化器的方法writeObject(Object, AbstractHessianOutput);

public interface Serializer {
  public void writeObject(Object obj, AbstractHessianOutput out) throws IOException;
}

默认序列化器JavaSerializer

public class JavaSerializer extends AbstractSerializer{
    public JavaSerializer(Class, ClassLoader){//...}
}

抽象工厂类定义了获取序列化和反序列化类的接口

abstract public class AbstractSerializerFactory {
    abstract public Serializer getSerializer(Class<?> cl) throws HessianProtocolException;

    abstract public Deserializer getDeserializer(Class<?> cl)throws HessianProtocolException;
}

工厂类SerializerFactory实现了获取序列化和反序列化类

public class SerializerFactory extends AbstractSerializerFactory{
    
}

public class Hessian2Output extends AbstractHessianOutput implements Hessian2Constants{
}


序列化举例

 

example.Car implements Serializable{

    private static final long serialVersionUID = 6209424312185142040L;
    
    private String color;
    
    private String model;
}

Car:{"color":"red","model":"corvette"}
序列化后的二进制:

 

43 b 65 78 61 6d 70 6c 65 2e 43 61 72 ffffff92 5 63 6f 6c 6f 72 5 6d 6f 64 65 6c 60 3 72 65 64 8 63 6f 72 76 65 74 74 65 40

序列化内容:
<类名><类属性数量><分别各个属性名称><分别各个属性的值>

下面对序列化后的二进制内容说明

#0x43=>C,表示对象类型
#x0b,表示类型是
#65 78 61 6d 70 6c 65 2e 43 61 72

 

String[] strs = "65 78 61 6d 70 6c 65 2e 43 61 72".split(" ");
for(String str : strs){
    System.out.print((char)Integer.parseInt(str, 16));
}

#打印结果:example.Car
#则是对象类型
#92,表示two fields类有两个属性
#0x05,表示属性名
#0x63 6f 6c 6f 72,表示属性名是color

 

String[] strs = "63 6f 6c 6f 72".split(" ");
for(String str : strs){
    System.out.print((char)Integer.parseInt(str, 16));
}

#打印结果:color
#0x05,表示属性名
#0x6d 6f 64 65 6c,表示属性名是model

 

String[] strs = "6d 6f 64 65 6c".split(" ");
for(String str : strs){
    System.out.print((char)Integer.parseInt(str, 16));
}

#打印结果:model
#0x60,表示值对象类型
#0x03,属性值长度3,red
#0x72 65 64

 

String[] strs = "72 65 64".split(" ");
for(String str : strs){
    System.out.print((char)Integer.parseInt(str, 16));
}

#打印结果:red
#0x08,属性值长度8,corvette
#0x63 6f 72 76 65 74 74 65

 

String[] strs = "63 6f 72 76 65 74 74 65".split(" ");
for(String str : strs){
    System.out.print((char)Integer.parseInt(str, 16));
}

#打印结果:corvette

序列化
通过对象的类获取类属性,再通过反射得到属性Field,再根据属性反射得到属性值,将属性值转成二进制
反序列化
通过反射得到类对象,反射得到类的属性Field,再根据属性和对象,将属性值设置给属性,这样反序列化得到完整的对象

对象属性嵌套对象属性:

 

public class Car implements Serializable{

    private static final long serialVersionUID = 6209424312185142040L;
    
    private String color;
    
    private String model;
    
    private Car car;//属性是对象类型
}


43 b 65 78 61 6d 70 6c 65 2e 43 61 72 ffffff93 5 63 6f 6c 6f 72 5 6d 6f 64 65 6c 3 63 61 72 60 3 72 65 64 8 63 6f 72 76 65 74 74 65 60 5 67 72 65 65 6e 3 6d 6f 6f 4e 56
{"color":"red","model":"corvette","car":{"color":"green","model":"moo"}}

例如netty作为client,server。
client-com.alibaba.dubbo.remoting.transport.netty.NettyClient,
server-com.alibaba.dubbo.remoting.transport.netty.NettyServer,
client,server收发消息时,
序列化
-使用com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter.InternalEncoder.encode(ChannelHandlerContext ctx, Channel ch, Object msg)
--com.alibaba.com.caucho.hessian.io.Hessian2Output.writeObject(Object object)
反序列化
-使用com.alibaba.dubbo.remoting.transport.netty.NettyCodecAdapter.InternalDecoder.messageReceived(ChannelHandlerContext, MessageEvent)

 

--com.alibaba.com.caucho.hessian.io.Hessian2Input.readObject()

 

自己写了个RPC:

https://github.com/nytta

可以给个star,^0^.

参考:

http://hessian.caucho.com/doc/hessian-serialization.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值