Hessian 协议解释与实战(五):对象与映射

Hessian 协议解释与实战(五):对象与映射

前段时间,翻译了 Hessian 2.0 的序列化协议,发布在了 Hessian 2.0 序列化协议(中文版)。但是,其中有很多言语不详之处。所以,接下来会用几篇文章来详细解释并实践一下 Hessian 序列化协议,以求做到知其然知其所以然。目录如下:

  1. Hessian 2.0 序列化协议(中文版) — Hessian 序列化协议的中文翻译版。根据后面的“协议解释与实战”系列文章,增加了协议内容错误提示。

  2. Hessian 协议解释与实战(一):布尔、日期、浮点数与整数 — 介绍布尔型数据、日期类型、浮点类型数据和整数类型数据等四种类型的数据的处理。

  3. Hessian 协议解释与实战(二):长整型、二进制数据与 Null — 介绍长整数类型数据、二进制数据和 null 等三种类型的数据的处理。

  4. Hessian 协议解释与实战(三):字符串 — 专门介绍了关于字符串的处理。由于字符串需要铺垫的基础知识比较多,处理细节也有繁琐,所以单独成篇来介绍。

  5. Hessian 源码分析(Java) — 开始第四篇分析之前,先来介绍一下 Hessian 的源码实现。方便后续展开说明。

  6. Hessian 协议解释与实战(四):数组与集合 — 铺垫了一些关于实例对象的处理,重点介绍关于数组和集合的相关处理。

  7. Hessian 协议解释与实战(五):对象与映射 — 重点介绍关于对象与映射的相关处理。

  8. Hessian、Msgpack 和 JSON 实例对比 — 用实例对比 JSON、Hessian 和 MessagePack 的区别。

  9. Avro、ProtoBuf、Thrift 的模式演进之路 — 翻译的 Martin Kleppmann 的文章,重点对比了 Avro、ProtoBuf、Thrift 的序列化处理思路。

在上一篇文章 Hessian 协议解释与实战(四):数组与集合 中研究了数组和集合的处理方式。接下来介绍对象和映射的处理。

基础工具方法

基础工具方法就不再赘述,请直接参考 Hessian 协议解释与实战(一):基础工具方法 中提到的几个方法。

另外,在 Hessian 协议解释与实战(四):数组与集合 中,又对一些方法做了扩展和更新。

下面,我们来看一看映射的处理。

映射

坦白讲,个人觉得 Hessian 2.0 序列化协议(中文版):映射 的协议定义写的非常模糊。倒是给的示例,还可圈可点。

相关代码实现

通过 Hessian 源码分析(Java) 可以指定, MapSerializer 是处理映射的 Serializer。所以,只需要关注一下 MapSerializer 就可以对映射的处理一目了然。结合代码,可以看出,映射的序列化流程大致如下:

  1. AbstractHessianOutput.writeMapBegin(String type) — 写入映射起始信息;

  2. 遍历 Map.Entry,并且是先序列化 Key,然后序列化 Value;

  3. AbstractHessianOutput.writeMapEnd() — 写入映射结束信息。

另外,在 Hessian 源码分析(Java) 中,也提到在 Hessian2Output 中实现了 AbstractHessianOutput 的接口。所以,只需要关注 Hessian2Output 对上述方法的实现即可。

Hessian2Output 中可以看出:

  1. Hessian2Output.writeMapBegin(String type) 有两个类型:

    1. 需要写入类型: M,前置标志位后是映射类型信息;

    2. 不需要写入类型: H,这里没有写入类型信息。

  2. AbstractHessianOutput.writeMapEnd() — 映射结束信息只有一个结束标志位: Z。这个标志位,在 Hessian 协议解释与实战(四):数组与集合: Collection<Integer>.iterator 👉 IteratorSerializer 中也用到了。

下面开始做实验来验证。

HashMap

接下来,我们看一下序列化操作:

/**
 * 测试 HashMap 的序列化
 *
 * @author D瓜哥 · https://www.diguage.com/
 */
@Test
public void testHashMap() throws Throwable {
    // 由 MapSerializer 来处理。分三步来处理:
    // 1、首先,写入前置标志位 BC_MAP_UNTYPED = 'H'
    // 2、其次,遍历 Map.Entry,并将其序列化:①Key ②Value
    // 3、最后,写入结束标志位 BC_END = 'Z'
    Map<Integer, Car> map = new HashMap<>();
    map.put(1, new Car("diguage", 47));
    objectTo(map);
}


// -- 输出结果 ------------------------------------------------
== Object: java.util.HashMap  ==
== Key Object: java.lang.Integer  ==
== Val Object: com.diguage.Car  ==
{"1":{"name":"diguage","age":47}}
== byte array: hessian result ==
.... 0 ~ 40 ....
  72 0x48 01001000 H
-111 0x91 10010001
  67 0x43 01000011 C
  15 0x0F 00001111 
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  67 0x43 01000011 C
  97 0x61 01100001 a
 114 0x72 01110010 r
-110 0x92 10010010
   4 0x04 00000100 
 110 0x6E 01101110 n
  97 0x61 01100001 a
 109 0x6D 01101101 m
 101 0x65 01100101 e
   3 0x03 00000011 
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  96 0x60 01100000 `
   7 0x07 00000111 
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
 -65 0xBF 10111111
  90 0x5A 01011010 Z

从结果上来看,跟我们上面的分析差不多,确定了一些细节:

  1. 首先,写入前置标志位 0x48H

  2. 其次,遍历 Map.Entry,并将其序列化

    1. Key

    2. Value

  3. 最后,写入结束标志位 0x5AZ)。

接下来再看看其他类型的 Map 的处理情况。

TreeMap

来看看 TreeMap 的处理情况:

/**
 * 测试 TreeMap 的序列化
 *
 * @author D瓜哥 · https://www.diguage.com/
 */
@Test
public void testTreeMap() throws Throwable {
    Car c = new Car("diguage", 47);
    Map<Integer, Car> map = new TreeMap<>();
    map.put(1, c);
    objectTo(map);
}


// -- 输出结果 ------------------------------------------------
== Object: java.util.TreeMap  ==
== Key Object: java.lang.Integer  ==
== Val Object: com.diguage.Car  ==
{"1":{"name":"diguage","age":47}}
== byte array: hessian result ==
.... 0 ~ 58 ....
  77 0x4D 01001101 M
  17 0x11 00010001 
 106 0x6A 01101010 j
  97 0x61 01100001 a
 118 0x76 01110110 v
  97 0x61 01100001 a
  46 0x2E 00101110 .
 117 0x75 01110101 u
 116 0x74 01110100 t
 105 0x69 01101001 i
 108 0x6C 01101100 l
  46 0x2E 00101110 .
  84 0x54 01010100 T
 114 0x72 01110010 r
 101 0x65 01100101 e
 101 0x65 01100101 e
  77 0x4D 01001101 M
  97 0x61 01100001 a
 112 0x70 01110000 p
-111 0x91 10010001
  67 0x43 01000011 C
  15 0x0F 00001111 
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  67 0x43 01000011 C
  97 0x61 01100001 a
 114 0x72 01110010 r
-110 0x92 10010010
   4 0x04 00000100 
 110 0x6E 01101110 n
  97 0x61 01100001 a
 109 0x6D 01101101 m
 101 0x65 01100101 e
   3 0x03 00000011 
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  96 0x60 01100000 `
   7 0x07 00000111 
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
 -65 0xBF 10111111
  90 0x5A 01011010 Z

针对 TreeMap 的处理,大致也可以分为三步:

  1. 首先,写入前置信息:

    1. 写入前置标志位 0x4DM

    2. 写入 Map 的类型(字符串形式)

  2. 其次,遍历 Map.Entry,并将其序列化

    1. Key

    2. Value

  3. 最后,写入结束标志位 0x5AZ)。

HashMap 不同之处时,这里写入了 Map 的类型信息。所以,相比来说 HashMap 更加轻量级。在做微服务接口的参数和返回结果时,可以优先考虑 HashMap

再谈实例对象

为了方便叙述,在 Hessian 协议解释与实战(四):数组与集合:首谈实例对象 中,对对象的处理做了简要的概述。到这里,让我们再来认识一下实例对象。

处理实例对象的序列化主要有 JavaSerializerBeanSerializer。这两者的区别如下:

  • JavaSerializer 是通过反射获取实例对象的属性进行序列化。排除 statictransient 属性,对其他所有的属性进行递归序列化处理。

  • BeanSerializer 是遵循 POJI bean 的约定,扫描实例的所有方法,发现同时存在 Getter 和 Setter 方法的属性才进行序列化,它并不直接直接操作所有的属性。注意: BeanSerializer 将会无法处理 Getter 方法是以 is 开头的 boolean 属性,因为 BeanSerializer 只认以 get 开头的方法。

在 Java 8 中,其实默认使用的并不是这两个,而是 UnsafeSerializer。它与 JavaSerializer 相似,都是通过反射获取类的属性列表;但是与 JavaSerializer 不同之处时, JavaSerializer 通过 Field 使用反射获取实例对象属性对应的值;而 UnsafeSerializer 是使用 sun.misc.Unsafe 来获取字段的“指针”(offset),再通过“指针”获取实例对象属性对应的值。

另外,启用 UnsafeSerializer 的先决条件是能否获得 sun.misc.Unsafe 实例。如果可以获得 sun.misc.Unsafe 实例,则就会启用 UnsafeSerializer。当然,也可以通过配置 com.caucho.hessian.unsafe 变量为 false 来禁用 UnsafeSerializer。这里,还有一个例外:如果待序列化的类包含了 writeReplace() 方法,则就会启用 JavaSerializer

下面介绍一下继承对象的序列化情况:

继承对象

父类
package com.diguage;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 用户
 *
 * @author D瓜哥 · https://www.diguage.com
 */
public class User {
    private Integer id;
    private String name;
    private Date birthday;
    private BigDecimal money;

    public User() {
    }

    public User(Integer id, String name, Date birthday, BigDecimal money) {
        this.id = id;
        this.name = name;
        this.birthday = birthday;
        this.money = money;
    }

    // 各种 Setter 和 Getter 方法
}
子类
package com.diguage;

import java.math.BigDecimal;
import java.util.Date;

/**
 * Web用户
 *
 * @author D瓜哥 · https://www.diguage.com
 */
public class WebUser extends User {
    private String site;

    public WebUser() {
    }

    public WebUser(Integer id, String name, Date birthday, BigDecimal money, String site) {
        super(id, name, birthday, money);
        this.site = site;
    }

    // 各种 Setter 和 Getter 方法
}
/**
 * 测试父子类的序列化
 *
 * @author D瓜哥 · https://www.diguage.com
 */
@Test
public void testInheritance() throws Throwable {
    BigDecimal money = new BigDecimal("1234.56789")
            .setScale(2, BigDecimal.ROUND_HALF_UP);
    int id = 4;
    String name = "diguage";
    Date date = new Date();
    String site = "https://www.diguage.com";
    WebUser webUser = new WebUser(id, name, date, money, site);
    objectTo(webUser);
}


// -- 输出结果 ------------------------------------------------
== Object: com.diguage.WebUser  ==
== object: json length=107 ==
{
  "id": 4,
  "name": "diguage",
  "birthday": "2022-08-05 19:37:15",
  "money": 1234.57,
  "site": "https://www.diguage.com"
}
== object: hessian result ==
.... 0 ~ 131 ....
  67 0x43 01000011 C
  19 0x13 00010011 
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  87 0x57 01010111 W
 101 0x65 01100101 e
  98 0x62 01100010 b
  85 0x55 01010101 U
 115 0x73 01110011 s
 101 0x65 01100101 e
 114 0x72 01110010 r
-107 0x95 10010101
   4 0x04 00000100 
 115 0x73 01110011 s
 105 0x69 01101001 i
 116 0x74 01110100 t
 101 0x65 01100101 e
   2 0x02 00000010 
 105 0x69 01101001 i
 100 0x64 01100100 d
   4 0x04 00000100 
 110 0x6E 01101110 n
  97 0x61 01100001 a
 109 0x6D 01101101 m
 101 0x65 01100101 e
   8 0x08 00001000
  98 0x62 01100010 b
 105 0x69 01101001 i
 114 0x72 01110010 r
 116 0x74 01110100 t
 104 0x68 01101000 h
 100 0x64 01100100 d
  97 0x61 01100001 a
 121 0x79 01111001 y
   5 0x05 00000101 
 109 0x6D 01101101 m
 111 0x6F 01101111 o
 110 0x6E 01101110 n
 101 0x65 01100101 e
 121 0x79 01111001 y
  96 0x60 01100000 `
  23 0x17 00010111 
 104 0x68 01101000 h
 116 0x74 01110100 t
 116 0x74 01110100 t
 112 0x70 01110000 p
 115 0x73 01110011 s
  58 0x3A 00111010 :
  47 0x2F 00101111 /
  47 0x2F 00101111 /
 119 0x77 01110111 w
 119 0x77 01110111 w
 119 0x77 01110111 w
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
-108 0x94 10010100
   7 0x07 00000111 
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  74 0x4A 01001010 J
   0 0x00 00000000
   0 0x00 00000000
   1 0x01 00000001 
-126 0x82 10000010
 109 0x6D 01101101 m
 -53 0xCB 11001011
-105 0x97 10010111
  -9 0xF7 11110111
  67 0x43 01000011 C
  20 0x14 00010100 
 106 0x6A 01101010 j
  97 0x61 01100001 a
 118 0x76 01110110 v
  97 0x61 01100001 a
  46 0x2E 00101110 .
 109 0x6D 01101101 m
  97 0x61 01100001 a
 116 0x74 01110100 t
 104 0x68 01101000 h
  46 0x2E 00101110 .
  66 0x42 01000010 B
 105 0x69 01101001 i
 103 0x67 01100111 g
  68 0x44 01000100 D
 101 0x65 01100101 e
  99 0x63 01100011 c
 105 0x69 01101001 i
 109 0x6D 01101101 m
  97 0x61 01100001 a
 108 0x6C 01101100 l
-111 0x91 10010001
   5 0x05 00000101 
 118 0x76 01110110 v
  97 0x61 01100001 a
 108 0x6C 01101100 l
 117 0x75 01110101 u
 101 0x65 01100101 e
  97 0x61 01100001 a
   7 0x07 00000111 
  49 0x31 00110001 1
  50 0x32 00110010 2
  51 0x33 00110011 3
  52 0x34 00110100 4
  46 0x2E 00101110 .
  53 0x35 00110101 5
  55 0x37 00110111 7

从序列化结果上来看,序列化有继承关系的实例对象时,会把对象按照子类一个类处理;但是,和没有继承关系又略有不同:有父子关系的实例对象会先处理子类的属性,然后再处理父类的属性。

重复字符串的处理

Hessian 协议解释与实战(四):数组与集合:首谈实例对象 中提到 “重复对象会使用前置标志位 0x51Q)+ 编号来处理”。对于字符串会怎么处理呢?下面做测试来验证一下:

/**
 * 测试重复字符串的序列化
 *
 * @author D瓜哥 · https://www.diguage.com
 */
@Test
public void testDuplicateString() throws Throwable {
    String string = "I'm D瓜哥,😁";
    List<String> strings = Arrays.asList(string, string);
    List<String> stringList = new ArrayList<>(strings);
    objectTo(stringList);
}


// -- 输出结果 ------------------------------------------------
== Object: java.util.ArrayList  ==
== Generic: java.lang.String  ==
== object: json length=27 ==
["I'm D瓜哥,😁","I'm D瓜哥,😁"]
== object: hessian result ==
.... 0 ~ 43 ....
 122 0x7A 01111010 z
  10 0x0A 00001010

  73 0x49 01001001 I
  39 0x27 00100111 '
 109 0x6D 01101101 m
  32 0x20 00100000
  68 0x44 01000100 D
 -25 0xE7 11100111
-109 0x93 10010011
-100 0x9C 10011100
 -27 0xE5 11100101
-109 0x93 10010011
 -91 0xA5 10100101
 -17 0xEF 11101111
 -68 0xBC 10111100
-116 0x8C 10001100
 -19 0xED 11101101
 -96 0xA0 10100000
 -67 0xBD 10111101
 -19 0xED 11101101
 -72 0xB8 10111000
-127 0x81 10000001
  10 0x0A 00001010

  73 0x49 01001001 I
  39 0x27 00100111 '
 109 0x6D 01101101 m
  32 0x20 00100000
  68 0x44 01000100 D
 -25 0xE7 11100111
-109 0x93 10010011
-100 0x9C 10011100
 -27 0xE5 11100101
-109 0x93 10010011
 -91 0xA5 10100101
 -17 0xEF 11101111
 -68 0xBC 10111100
-116 0x8C 10001100
 -19 0xED 11101101
 -96 0xA0 10100000
 -67 0xBD 10111101
 -19 0xED 11101101
 -72 0xB8 10111000
-127 0x81 10000001

从实验结果上来看,对于字符串来说, Hessian 并没有做特殊处理,遇到相同的字符串还是会反复序列化。

“混合”集合的序列化

有小伙伴提了一个问题:如果集合类是有各种各样对象的“混合”集合, Hessian 可以如何序列化的?下面做实验验证一下:

/**
 * 测试“混合”集合的序列化
 *
 * @author D瓜哥 · https://www.diguage.com
 */
@Test
public void testHybridList() throws Throwable {
    BigDecimal money = new BigDecimal("1234.56789")
            .setScale(2, BigDecimal.ROUND_HALF_UP);
    int id = 4;
    String name = "diguage";
    Date date = new Date();
    String site = "https://www.diguage.com";
    User user = new User(id, name, date, money);
    WebUser webUser = new WebUser(id, name, date, money, site);
    Car car = new Car(name, id);
    List<Object> hybridList = new ArrayList<>();
    // 在集合中,放了 WebUser、 User 和 Car 三个类型的实例对象
    hybridList.add(webUser);
    hybridList.add(user);
    hybridList.add(car);
    objectTo(hybridList);
}


// -- 输出结果 ------------------------------------------------
== Object: java.util.ArrayList  ==
== Generic: com.diguage.WebUser  ==
== object: json length=211下面是格式化代码 ==
[
  {
    "id": 4,
    "name": "diguage",
    "birthday": "2022-08-05 19:57:18",
    "money": 1234.57,
    "site": "https://www.diguage.com"
  },
  {
    "id": 4,
    "name": "diguage",
    "birthday": "2022-08-05 19:57:18",
    "money": 1234.57
  },
  {
    "name": "diguage",
    "age": 4
  }
]
== object: hessian result ==
.... 0 ~ 232 ....
 123 0x7B 01111011 {
  67 0x43 01000011 C
  19 0x13 00010011 
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  87 0x57 01010111 W
 101 0x65 01100101 e
  98 0x62 01100010 b
  85 0x55 01010101 U
 115 0x73 01110011 s
 101 0x65 01100101 e
 114 0x72 01110010 r
-107 0x95 10010101
   4 0x04 00000100 
 115 0x73 01110011 s
 105 0x69 01101001 i
 116 0x74 01110100 t
 101 0x65 01100101 e
   2 0x02 00000010 
 105 0x69 01101001 i
 100 0x64 01100100 d
   4 0x04 00000100 
 110 0x6E 01101110 n
  97 0x61 01100001 a
 109 0x6D 01101101 m
 101 0x65 01100101 e
   8 0x08 00001000
  98 0x62 01100010 b
 105 0x69 01101001 i
 114 0x72 01110010 r
 116 0x74 01110100 t
 104 0x68 01101000 h
 100 0x64 01100100 d
  97 0x61 01100001 a
 121 0x79 01111001 y
   5 0x05 00000101 
 109 0x6D 01101101 m
 111 0x6F 01101111 o
 110 0x6E 01101110 n
 101 0x65 01100101 e
 121 0x79 01111001 y
  96 0x60 01100000 `
  23 0x17 00010111 
 104 0x68 01101000 h
 116 0x74 01110100 t
 116 0x74 01110100 t
 112 0x70 01110000 p
 115 0x73 01110011 s
  58 0x3A 00111010 :
  47 0x2F 00101111 /
  47 0x2F 00101111 /
 119 0x77 01110111 w
 119 0x77 01110111 w
 119 0x77 01110111 w
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
-108 0x94 10010100
   7 0x07 00000111 
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  74 0x4A 01001010 J
   0 0x00 00000000
   0 0x00 00000000
   1 0x01 00000001 
-126 0x82 10000010
 109 0x6D 01101101 m
 -35 0xDD 11011101
 -14 0xF2 11110010
  21 0x15 00010101 
  67 0x43 01000011 C
  20 0x14 00010100 
 106 0x6A 01101010 j
  97 0x61 01100001 a
 118 0x76 01110110 v
  97 0x61 01100001 a
  46 0x2E 00101110 .
 109 0x6D 01101101 m
  97 0x61 01100001 a
 116 0x74 01110100 t
 104 0x68 01101000 h
  46 0x2E 00101110 .
  66 0x42 01000010 B
 105 0x69 01101001 i
 103 0x67 01100111 g
  68 0x44 01000100 D
 101 0x65 01100101 e
  99 0x63 01100011 c
 105 0x69 01101001 i
 109 0x6D 01101101 m
  97 0x61 01100001 a
 108 0x6C 01101100 l
-111 0x91 10010001
   5 0x05 00000101 
 118 0x76 01110110 v
  97 0x61 01100001 a
 108 0x6C 01101100 l
 117 0x75 01110101 u
 101 0x65 01100101 e
  97 0x61 01100001 a
   7 0x07 00000111 
  49 0x31 00110001 1
  50 0x32 00110010 2
  51 0x33 00110011 3
  52 0x34 00110100 4
  46 0x2E 00101110 .
  53 0x35 00110101 5
  55 0x37 00110111 7
  67 0x43 01000011 C
  16 0x10 00010000 
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  85 0x55 01010101 U
 115 0x73 01110011 s
 101 0x65 01100101 e
 114 0x72 01110010 r
-108 0x94 10010100
   2 0x02 00000010 
 105 0x69 01101001 i
 100 0x64 01100100 d
   4 0x04 00000100 
 110 0x6E 01101110 n
  97 0x61 01100001 a
 109 0x6D 01101101 m
 101 0x65 01100101 e
   8 0x08 00001000
  98 0x62 01100010 b
 105 0x69 01101001 i
 114 0x72 01110010 r
 116 0x74 01110100 t
 104 0x68 01101000 h
 100 0x64 01100100 d
  97 0x61 01100001 a
 121 0x79 01111001 y
   5 0x05 00000101 
 109 0x6D 01101101 m
 111 0x6F 01101111 o
 110 0x6E 01101110 n
 101 0x65 01100101 e
 121 0x79 01111001 y
  98 0x62 01100010 b
-108 0x94 10010100
   7 0x07 00000111 
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  74 0x4A 01001010 J
   0 0x00 00000000
   0 0x00 00000000
   1 0x01 00000001 
-126 0x82 10000010
 109 0x6D 01101101 m
 -35 0xDD 11011101
 -14 0xF2 11110010
  21 0x15 00010101 
  81 0x51 01010001 Q
-110 0x92 10010010
  67 0x43 01000011 C
  15 0x0F 00001111 
  99 0x63 01100011 c
 111 0x6F 01101111 o
 109 0x6D 01101101 m
  46 0x2E 00101110 .
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  46 0x2E 00101110 .
  67 0x43 01000011 C
  97 0x61 01100001 a
 114 0x72 01110010 r
-110 0x92 10010010
   4 0x04 00000100 
 110 0x6E 01101110 n
  97 0x61 01100001 a
 109 0x6D 01101101 m
 101 0x65 01100101 e
   3 0x03 00000011 
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
  99 0x63 01100011 c
   7 0x07 00000111 
 100 0x64 01100100 d
 105 0x69 01101001 i
 103 0x67 01100111 g
 117 0x75 01110101 u
  97 0x61 01100001 a
 103 0x67 01100111 g
 101 0x65 01100101 e
-108 0x94 10010100

从序列化结果上来看,和 Hessian 协议解释与实战(四):数组与集合:首谈实例对象 介绍的序列化方法是一致的。但是,这种在集合中混合各种各样对象的用法非常容易出问题,建议禁止这样编码!

总结

前面几篇文章介绍了各个前置标志位,这里做一个总结:

hessian bytecode