数据序列化-hessian2

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

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

接口Serializer定义了序列化器的方法writeObject(Object, AbstractHessianOutput);
  1. public interface Serializer {
  2. public void writeObject(Object obj, AbstractHessianOutput out) throws IOException;
  3. }
默认序列化器JavaSerializer
  1. public class JavaSerializer extends AbstractSerializer{
  2. public JavaSerializer(Class, ClassLoader){ //...}
  3. }
抽象工厂类定义了获取序列化和反序列化类的接口
  1. abstract public class AbstractSerializerFactory {
  2. abstract public Serializer getSerializer(Class<?> cl) throws HessianProtocolException;
  3. abstract public Deserializer getDeserializer(Class<?> cl)throws HessianProtocolException;
  4. }
工厂类SerializerFactory实现了获取序列化和反序列化类
  1. public class SerializerFactory extends AbstractSerializerFactory{
  2. }
  3. public class Hessian2Output extends AbstractHessianOutput implements Hessian2Constants{
  4. }

序列化举例
  1. example.Car implements Serializable{
  2. private static final long serialVersionUID = 6209424312185142040L;
  3. private String color;
  4. private String model;
  5. }
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
  1. String[] strs = "65 78 61 6d 70 6c 65 2e 43 61 72".split( " ");
  2. for(String str : strs){
  3. System.out.print(( char)Integer.parseInt(str, 16));
  4. }
#打印结果:example.Car
#则是对象类型
#92,表示two fields类有两个属性
#0x05,表示属性名
#0x63 6f 6c 6f 72,表示属性名是color
  1. String[] strs = "63 6f 6c 6f 72".split( " ");
  2. for(String str : strs){
  3. System.out.print(( char)Integer.parseInt(str, 16));
  4. }
#打印结果:color
#0x05,表示属性名
#0x6d 6f 64 65 6c,表示属性名是model
  1. String[] strs = "6d 6f 64 65 6c".split( " ");
  2. for(String str : strs){
  3. System.out.print(( char)Integer.parseInt(str, 16));
  4. }
#打印结果:model
#0x60,表示值对象类型
#0x03,属性值长度3,red
#0x72 65 64
  1. String[] strs = "72 65 64".split( " ");
  2. for(String str : strs){
  3. System.out.print(( char)Integer.parseInt(str, 16));
  4. }
#打印结果:red
#0x08,属性值长度8,corvette
#0x63 6f 72 76 65 74 74 65
  1. String[] strs = "63 6f 72 76 65 74 74 65".split( " ");
  2. for(String str : strs){
  3. System.out.print(( char)Integer.parseInt(str, 16));
  4. }
#打印结果:corvette

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

对象属性嵌套对象属性:
  1. public class Car implements Serializable{
  2. private static final long serialVersionUID = 6209424312185142040L;
  3. private String color;
  4. private String model;
  5. private Car car; //属性是对象类型
  6. }

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()


猜你喜欢

转载自blog.csdn.net/aa1215018028/article/details/80894657