hessian 2.0 序列化协议

Hessian 2.0 序列化协议翻译,原文链接http://hessian.caucho.com/doc/hessian-serialization.html

介绍

Hessian是一种动态类型的、采用二进制序列化的,并且被设计为面向对象传输的Web服务协议。

设计目标

Hessian是动态类型的,紧凑的,可跨语言移植的。

Hessian协议有以下几个设计目标:

  • It must self-describe the serialized types, i.e. not require external schema or interface definitions.
  • It must be language-independent, including supporting scripting languages.
  • It must be readable or writable in a single pass.
  • It must be as compact as possible.
  • It must be simple so it can be effectively tested and implemented.
  • It must be as fast as possible.
  • It must support Unicode strings.
  • It must support 8-bit binary data without escaping or using attachments.
  • It must support encryption, compression, signature, and transaction context envelopes.

Hessian 语法

序列化语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
           # starting production
top ::= value

# 8-bit binary data split into 64k chunks
binary ::= x41 b1 b0 <binary-data> binary # non-final chunk
::= 'B' b1 b0 <binary-data> # final chunk
::= [x20-x2f] <binary-data> # binary data of
# length 0-15
::= [x34-x37] <binary-data> # binary data of
# length 0-1023

# boolean true/false
boolean ::= 'T'
::= 'F'

# definition for an object (compact map)
class-def ::= 'C' string int string*

# time in UTC encoded as 64-bit long milliseconds since
# epoch
date ::= x4a b7 b6 b5 b4 b3 b2 b1 b0
::= x4b b3 b2 b1 b0 # minutes since epoch

# 64-bit IEEE double
double ::= 'D' b7 b6 b5 b4 b3 b2 b1 b0
::= x5b # 0.0
::= x5c # 1.0
::= x5d b0 # byte cast to double
# (-128.0 to 127.0)
::= x5e b1 b0 # short cast to double
::= x5f b3 b2 b1 b0 # 32-bit float cast to double

# 32-bit signed integer
int ::= 'I' b3 b2 b1 b0
::= [x80-xbf] # -x10 to x3f
::= [xc0-xcf] b0 # -x800 to x7ff
::= [xd0-xd7] b1 b0 # -x40000 to x3ffff

# list/vector
list ::= x55 type value* 'Z' # variable-length list
::= 'V' type int value* # fixed-length list
::= x57 value* 'Z' # variable-length untyped list
::= x58 int value* # fixed-length untyped list
::= [x70-77] type value* # fixed-length typed list
::= [x78-7f] value* # fixed-length untyped list

# 64-bit signed long integer
long ::= 'L' b7 b6 b5 b4 b3 b2 b1 b0
::= [xd8-xef] # -x08 to x0f
::= [xf0-xff] b0 # -x800 to x7ff
::= [x38-x3f] b1 b0 # -x40000 to x3ffff
::= x59 b3 b2 b1 b0 # 32-bit integer cast to long

# map/object
map ::= 'M' type (value value)* 'Z' # key, value map pairs
::= 'H' (value value)* 'Z' # untyped key, value

# null value
null ::= 'N'

# Object instance
object ::= 'O' int value*
::= [x60-x6f] value*

# value reference (e.g. circular trees and graphs)
ref ::= x51 int # reference to nth map/list/object

# UTF-8 encoded character string split into 64k chunks
string ::= x52 b1 b0 <utf8-data> string # non-final chunk
::= 'S' b1 b0 <utf8-data> # string of length
# 0-65535
::= [x00-x1f] <utf8-data> # string of length
# 0-31
::= [x30-x34] <utf8-data> # string of length
# 0-1023

# map/list types for OO languages
type ::= string # type name
::= int # type reference

# main production
value ::= null
::= binary
::= boolean
::= class-def value
::= date
::= double
::= int
::= list
::= long
::= map
::= object
::= ref
::= string

序列化

Hessian的对象序列化有8个原始类型:

  • raw binary data
  • boolean
  • 64-bit millisecond date
  • 64-bit double
  • 32-bit int
  • 64-bit long
  • null
  • UTF8-encoded string

它有3个递归类型:

  • list for lists and arrays
  • map for maps and dictionaries
  • object for objects

最后,它有一个特殊的构造:

  • ref for shared and circular object references.

Hessian 2.0 有三个内置引用类型映射:

  • An object/list reference map.
  • An class definition reference map.
  • A type (class name) reference map.

二进制数据

二进制数据语法

1
2
3
binary ::= b b1 b0 <binary-data> binary
::= B b1 b0 <binary-data>
::= [x20-x2f] <binary-data>

二进制数据使用块编码。八进制 0x42('B')编码最后一个块,0x62('b')表示除了最后一个块以外的块。每个块都有一个16位的长度值。长度值公式:

len = 256 * b1 + b0

压缩短二进制

长度小于15的二进制数据采用一个八进制数据表示长度,该八进制数据取值范围:[x20-x2f],长度值公式:

len = code - 0x20

二进制示例

1
2
3
4
5
6
7
x20               # 0长度二进制数据

x23 x01 x02 x03 # 3个八字节数据

B x10 x00 .... # 4k 结尾数据块

b x04 x00 .... # 1k 非结尾数据块

boolean

Boolean语法

1
2
boolean ::= T
::= F

字节 'F' 表示false,字节 'T' 表示true

Boolean 示例

1
2
T   # true
F # false

date

Date 语法

1
2
date ::= x4a b7 b6 b5 b4 b3 b2 b1 b0
::= x4b b4 b3 b2 b1 b0

日期类型使用一个64位的long数值表示从1970-01-01 00:00:00以来经过的毫秒数。

压缩:使用分钟表示日期

第二种方式是使用一个32位的int数值表示从1970-01-01 00:00以来经过的分钟数。

日期 示例

1
2
3
x4a x00 x00 x00 xd0 x4b x92 x84 xb8   # 09:51:31 1998年5月8日UTC

x4b x4b x92 x0b xa0 # 09:51:00 1998年5月8日UTC

double

Double 语法

1
2
3
4
5
6
double ::= D b7 b6 b5 b4 b3 b2 b1 b0
::= x5b
::= x5c
::= x5d b0
::= x5e b1 b0
::= x5f b3 b2 b1 b0

一个64位的IEEE标准的浮点数。

压缩:double zero

double类型的0.0可以使用字节x5b表示。

压缩:double one

double类型的1.0可以使用字节x5c表示。

压缩: double octet

介于-128.0127.0 之间,且没有小数部分的double数值可以使用两个字节表示。转换公式:

1
value = (double) b0

压缩: double short

介于-32768.032767.0 之间,且没有小数部分的double数值可以使用三个字节表示。转换公式:

1
value = (double) (256 * b1 + b0)

压缩: double float

Doubles which are equivalent to their 32-bit float representation can be represented as the 4-octet float and then cast to double.

Double 示例

1
2
3
4
5
6
7
8
9
10
11
12
x5b          # 0.0
x5c # 1.0

x5d x00 # 0.0
x5d x80 # -128.0
x5d x7f # 127.0

x5e x00 x00 # 0.0
x5e x80 x00 # -32768.0
x5e x7f xff # 32767.0

D x40 x28 x80 x00 x00 x00 x00 x00 # 12.25

int

Integer 语法:

1
2
3
4
int ::= 'I' b3 b2 b1 b0
::= [x80-xbf]
::= [xc0-xcf] b0
::= [xd0-xd7] b1 b0

A 32-bit signed integer. An integer is represented by the octet x49 ('I') followed by the 4 octets of the integer in big-endian order.

value = (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;

压缩:单字节整数

介于-1647 之间的整数可以使用单个位于[x80, xbf]范围内的字节表示。转换公式:

1
value = code - 0x90

压缩:双字节整数

介于-20482047 之间的整数可以使用两个字节表示,首字节位于[xc0, xcf]范围内。转换公式:

1
value = ((code - 0xc8) << 8) + b0;

压缩:三字节整数

介于-262144262143 之间的整数可以使用三个字节表示,首字节位于[xd0, xd7]范围内。转换公式:

1
value = ((code - 0xd4) << 16) + (b1 << 8) + b0;

Integer 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x90                # 0
x80 # -16
xbf # 47

xc8 x00 # 0
xc0 x00 # -2048
xc7 x00 # -256
xcf xff # 2047

xd4 x00 x00 # 0
xd0 x00 x00 # -262144
xd7 xff xff # 262143

I x00 x00 x00 x00 # 0
I x00 x00 x01 x2c # 300

list

List 语法

1
2
3
4
5
6
list ::= x55 type value* 'Z'   # variable-length list
::= 'V' type int value* # fixed-length list
::= x57 value* 'Z' # variable-length untyped list
::= x58 int value* # fixed-length untyped list
::= [x70-77] type value* # fixed-length typed list
::= [x78-7f] value* # fixed-length untyped list

An ordered list, like an array. The two list productions are a fixed-length list and a variable length list. Both lists have a type. The type string may be an arbitrary UTF-8 string understood by the service.

Each list item is added to the reference list to handle shared and circular elements. See the ref element.

Any parser expecting a list must also accept a null or a shared ref.

The valid values of type are not specified in this document and may depend on the specific application. For example, a server implemented in a language with static typing which exposes an Hessian interface can use the type information to instantiate the specific array type. On the other hand, a server written in a dynamicly-typed language would likely ignore the contents of type entirely and create a generic array.

Compact: fixed length list

Hessian 2.0 allows a compact form of the list for successive lists of the same type where the length is known beforehand. The type and length are encoded by integers, where the type is a reference to an earlier specified type.

List 示例

序列化一个整数数组: int[] = {0, 1}

1
2
3
4
5
V                    # fixed length, typed list
x04 [int # encoding of int[] type
x92 # length = 2
x90 # integer 0
x91 # integer 1

可变长度,无类型: list = {0, 1}

1
2
3
4
x57                  # variable-length, untyped
x90 # integer 0
x91 # integer 1
Z

固定长度,限制类型:

1
2
3
4
5
6
7
8
9
10
x72                # typed list length=2
x04 [int # type for int[] (save as type #0)
x90 # integer 0
x91 # integer 1

x73 # typed list length = 3
x90 # type reference to int[] (integer #0)
x92 # integer 2
x93 # integer 3
x94 # integer 4

long

Long 语法

1
2
3
4
5
long ::= L b7 b6 b5 b4 b3 b2 b1 b0
::= [xd8-xef]
::= [xf0-xff] b0
::= [x38-x3f] b1 b0
::= x4c b3 b2 b1 b0

A 64-bit signed integer. An long is represented by the octet x4c ('L' ) followed by the 8-bytes of the integer in big-endian order.

64位有符号的整数。一个long类型数值使用字节0x4c('L')开头,后面跟着8个字节的大端整数表示。

压缩:单字节long

Longs between -8 and 15 are represented by a single octet in the range xd8 to xef.

介于-815之间的long类型,使用一个取值范围在[0xd8, 0xef]的八进制表示。转换公式:

value = (code - 0xe0)

压缩:双字节long

Longs between -2048 and 2047 are encoded in two octets with the leading byte in the range xf0 to xff.

介于-20482047之间的long类型,使用两个八进制数值表示,其中首字节取值范围在[0xf0, 0xff]。转换公式:

value = ((code - 0xf8) << 8) + b0

压缩:三字节long

Longs between -262144 and 262143 are encoded in three octets with the leading byte in the range x38 to x3f.

介于-262144262143之间的long类型,使用三个八进制数值表示,其中首字节取值范围在[0x38, 0x3f]。转换公式:

value = ((code - 0x3c) << 16) + (b1 << 8) + b0

压缩:四字节long

Longs between which fit into 32-bits are encoded in five octets with the leading byte x4c.

不超过32位的long类型数值,采用5个字节编码,其中首字节为0x4c。转换公式:

value = (b3 << 24) + (b2 << 16) + (b1 << 8) + b0

Long 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
xe0                  # 0
xd8 # -8
xef # 15

xf8 x00 # 0
xf0 x00 # -2048
xf7 x00 # -256
xff xff # 2047

x3c x00 x00 # 0
x38 x00 x00 # -262144
x3f xff xff # 262143

x4c x00 x00 x00 x00 # 0
x4c x00 x00 x01 x2c # 300

L x00 x00 x00 x00 x00 x00 x01 x2c # 300

map

Map 语法

1
map        ::= M type (value value)* Z

Represents serialized maps and can represent objects. The type element describes the type of the map.

代表一个序列化的map,也可以表示一个对象。type元素描述了map的类型。

The type may be empty, i.e. a zero length. The parser is responsible for choosing a type if one is not specified. For objects, unrecognized keys will be ignored.

type元素可能为空,即零长度。当type未指定时,由解析器负责选择一个类型。对于object,不能识别的key将会被忽略。

Each map is added to the reference list. Any time the parser expects a map, it must also be able to support a null or a ref.

每一个映射都将被添加到参考集合中。任何时候,解析器都期望有一个映射,它必须支持null或者一个引用。

The type is chosen by the service.

类型由service选择。

Map 示例

稀疏数组:

1
2
3
4
map = new HashMap();
map.put(new Integer(1), "fee");
map.put(new Integer(16), "fie");
map.put(new Integer(256), "foe");

1
2
3
4
5
6
7
8
9
10
11
H           # untyped map (HashMap for Java)
x91 # 1
x03 fee # "fee"

xa0 # 16
x03 fie # "fie"

xc9 x00 # 256
x03 foe # "foe"

Z

Java对象的map表示:

1
2
3
4
5
public class Car implements Serializable {
String color = "aquamarine";
String model = "Beetle";
int mileage = 65536;
}

1
2
3
4
5
6
7
8
9
10
11
12
M
x13 com.caucho.test.Car # type

x05 color # color field
x0a aquamarine

x05 model # model field
x06 Beetle

x07 mileage # mileage field
I x00 x01 x00 x00
Z

null

Null 语法

1
null ::= N

Null 表示空指针。字节 'N' 表示null值。

object

Object 语法

1
2
3
4
class-def  ::= 'C' string int string*

object ::= 'O' int value*
::= [x60-x6f] value*

压缩: class definition

Hessian 2.0 has a compact object form where the field names are only serialized once.

Hessian 2.0具有紧凑的对象形式,其中字段名称仅被序列化一次。

Following objects only need to serialize their values.

之后的对象,只需要序列化它们的值。

The object definition includes a mandatory type string, the number of fields, and the field names. The object definition is stored in the object definition map and will be referenced by object instances with an integer reference.

压缩: object instantiation

Hessian 2.0 has a compact object form where the field names are only serialized once. Following objects only need to serialize their values.

Hessian 2.0具有紧凑的对象形式,其中字段名称仅被序列化一次。

The object instantiation creates a new object based on a previous definition. The integer value refers to the object definition.

对象实例基于前面的定义创建一个新对象。使用一个整数指向对象的定义。

Object 示例

Object 序列化:

1
2
3
4
5
6
7
class Car {
String color;
String model;
}

out.writeObject(new Car("red", "corvette"));
out.writeObject(new Car("green", "civic"));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
C                        # object definition (#0)
x0b example.Car # type is example.Car
x92 # two fields
x05 color # color field name
x05 model # model field name

O # object def (long form)
x90 # object definition #0
x03 red # color field value
x08 corvette # model field value

x60 # object def #0 (short form)
x05 green # color field value
x05 civic # model field value

枚举类型:

1
2
3
4
5
6
7
8
9
10
 enum Color {
RED,
GREEN,
BLUE,
}

out.writeObject(Color.RED);
out.writeObject(Color.GREEN);
out.writeObject(Color.BLUE);
out.writeObject(Color.GREEN);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
C                         # class definition #0
x0b example.Color # type is example.Color
x91 # one field
x04 name # enumeration field is "name"

x60 # object #0 (class def #0)
x03 RED # RED value

x60 # object #1 (class def #0)
x90 # object definition ref #0
x05 GREEN # GREEN value

x60 # object #2 (class def #0)
x04 BLUE # BLUE value

x51 x91 # object ref #1, i.e. Color.GREEN

ref

Ref 语法

1
ref ::= x51 int

An integer referring to a previous list, map, or object instance. As each list, map or object is read from the input stream, it is assigned the integer position in the stream, i.e. the first list or map is '0', the next is '1', etc. A later ref can then use the previous object. Writers MAY generate refs. Parsers MUST be able to recognize them.

一个整数指向一个前面的list、map或者一个对象实例。对于每一个从输入流中读到的list、map或者对象,它都被指定了一个整数的位置,即,第一个list或map的位置是0,下一个是1,等等。后面的引用可以指向前面的对象。写入器可能会生成引用,解析器一定要能够注册它们。

译者注:ref可以理解为指针。

ref can refer to incompletely-read items. For example, a circular linked-list will refer to the first link before the entire list has been read.

ref可以指向一个已经读取完的项。例如:一个循环链表在整个读取完之前,可能会指向第一个链接。

A possible implementation would add each map, list, and object to an array as it is read. The ref will return the corresponding value from the array. To support circular structures, the implementation would store the map, list or object immediately, before filling in the contents.

Each map or list is stored into an array as it is parsed. ref selects one of the stored objects. The first object is numbered '0'.

Ref 示例

Circular list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
list = new LinkedList();
list.data = 1;
list.tail = list;

---
C
x0a LinkedList
x92
x04 head
x04 tail

o x90 # object stores ref #0
x91 # data = 1
x51 x90 # next field refers to itself, i.e. ref #0

ref only refers to list, map and objects elements. Strings and binary data, in particular, will only share references if they're wrapped in a list or map.

string

String 语法

1
2
3
4
string ::= x52 b1 b0 <utf8-data> string
::= S b1 b0 <utf8-data>
::= [x00-x1f] <utf8-data>
::= [x30-x33] b0 <utf8-data>

A 16-bit unicode character string encoded in UTF-8. Strings are encoded in chunks. x53 ('S') represents the final chunk and x52 ('R') represents any non-final chunk. Each chunk has a 16-bit unsigned integer length value.

String是以UTF-8编码的16位的unicode字符串。String使用块编码。0x53('S')表示最后一个块,0x52('R')表示除了最后一个块以外的块。每个块都有一个16位的长度值。

The length is the number of 16-bit characters, which may be different than the number of bytes.

长度是指16位字符的长度,可能和字节的数量不一样。

String chunks may not split surrogate pairs.

压缩: short strings

Strings with length less than 32 may be encoded with a single octet length [x00-x1f].

长度少于32的字符串使用一个范围在[x00-x1f]的八进制数值编码它的长度。计算公式:

value = code

String 示例

1
2
3
4
5
6
7
8
x00                 # "", empty string
x05 hello # "hello"
x01 xc3 x83 # "\u00c3"

S x00 x05 hello # "hello" in long form

x52 x00 x07 hello, # "hello, world" split into two chunks
x05 world

type

Type 语法

1
2
type ::= string
::= int

A map or list includes a type attribute indicating the type name of the map or list for object-oriented languages.

Each type is added to the type map for future reference.

压缩: type 引用

Repeated type strings MAY use the type map to refer to a previously used type. The type reference is zero-based over all the types encountered during parsing.

引用映射

Hessian 2.0 有三种内置引用映射:

  • An map/object/list reference map.
  • An class definition map.
  • A type (class name) map.

The value reference map lets Hessian support arbitrary graphs, and recursive and circular data structures.

The class and type maps improve Hessian efficiency by avoiding repetition of common string data.

值引用

Hessian supports arbitrary graphs by adding list, object, and map as it encounters them in the bytecode stream.

Parsers MUST store each list, object and map in the reference map as they are encountered.

The stored objects can be used with a ref bytecode.

class 引用

Each object definition is automatically added to the class-map. Parsers MUST add a class definition to the class map as each is encountered. Following object instances will refer to the defined class.

type 引用

The type strings for map and list values are stored in a type map for reference.

Parsers MUST add a type string to the type map as each is encountered.

字节映射

Hessian is organized as a bytecode protocol. A Hessian reader is essentially a switch statement on the initial octet.

字节编码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
x00 - x1f    # utf-8 string length 0-32
x20 - x2f # binary data length 0-16
x30 - x33 # utf-8 string length 0-1023
x34 - x37 # binary data length 0-1023
x38 - x3f # three-octet compact long (-x40000 to x3ffff)
x40 # reserved (expansion/escape)
x41 # 8-bit binary data non-final chunk ('A')
x42 # 8-bit binary data final chunk ('B')
x43 # object type definition ('C')
x44 # 64-bit IEEE encoded double ('D')
x45 # reserved
x46 # boolean false ('F')
x47 # reserved
x48 # untyped map ('H')
x49 # 32-bit signed integer ('I')
x4a # 64-bit UTC millisecond date
x4b # 32-bit UTC minute date
x4c # 64-bit signed long integer ('L')
x4d # map with type ('M')
x4e # null ('N')
x4f # object instance ('O')
x50 # reserved
x51 # reference to map/list/object - integer ('Q')
x52 # utf-8 string non-final chunk ('R')
x53 # utf-8 string final chunk ('S')
x54 # boolean true ('T')
x55 # variable-length list/vector ('U')
x56 # fixed-length list/vector ('V')
x57 # variable-length untyped list/vector ('W')
x58 # fixed-length untyped list/vector ('X')
x59 # long encoded as 32-bit int ('Y')
x5a # list/map terminator ('Z')
x5b # double 0.0
x5c # double 1.0
x5d # double represented as byte (-128.0 to 127.0)
x5e # double represented as short (-32768.0 to 327676.0)
x5f # double represented as float
x60 - x6f # object with direct type
x70 - x77 # fixed list with direct length
x78 - x7f # fixed untyped list with direct length
x80 - xbf # one-octet compact int (-x10 to x3f, x90 is 0)
xc0 - xcf # two-octet compact int (-x800 to x7ff)
xd0 - xd7 # three-octet compact int (-x40000 to x3ffff)
xd8 - xef # one-octet compact long (-x8 to xf, xe0 is 0)
xf0 - xff # two-octet compact long (-x800 to x7ff, xf8 is 0)

作者联系方式

1
2
3
4
5
6
Scott Ferguson
Caucho Technology Inc.
P.O. Box 9001
La Jolla, CA 92038
USA
Email: ferg@caucho.com

1
2
3
4
5
6
Emil Ong
Caucho Technology Inc.
P.O. Box 9001
La Jolla, CA 92038
USA
Email: emil@caucho.com

Full Copyright Statement

Copyright © The IETF Trust (2007).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an “AS IS” basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

hessian 序列化