一、MessagePack MessagePack官网如下介绍。
It’s like JSON. but fast and small.
MessagePack is an efficient binary serialization format. It lets you exchange data among multiple languages like JSON. But it’s faster and smaller. Small integers are encoded into a single byte, and typical short strings require only one extra byte in addition to the strings themselves.
MessagePack是一个高效的二进制序列化格式。他像Json一样可以跨语言传输数据。但是比json更小更快。短整形被编码为单字节,短字符串也只需要附加额外的几个字节。
二、查看Java对象生成的Tempalte类 1)类原始信息
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 package pers.kivi.javafragment.msgpack;public class Person { String name; String mail; int age; public Person () { } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
2)MessagePack生成的Template
Template通过HSDB进行创建,参考使用HSDB查看运行时类
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 package pers.kivi.javafragment.msgpack;import java.io.IOException;import org.msgpack.MessageTypeException;import org.msgpack.packer.Packer;import org.msgpack.template.Template;import org.msgpack.template.builder.JavassistTemplateBuilder.JavassistTemplate;import org.msgpack.unpacker.Unpacker;public class Person_$$_Template_1983747920_0 extends JavassistTemplate implements Template { public Person_$$_Template_1983747920_0(Class var1, Template[] var2) { super (var1, var2); } public void write (Packer var1, Object var2, boolean var3) throws IOException { if (var2 == null ) { if (var3) { throw new MessageTypeException ("Attempted to write null" ); } else { var1.writeNil(); } } else { Person var4 = (Person)var2; var1.writeArrayBegin(3 ); if (var4.name == null ) { var1.writeNil(); } else { super .templates[0 ].write(var1, var4.name); } if (var4.mail == null ) { var1.writeNil(); } else { super .templates[1 ].write(var1, var4.mail); } var1.write(var4.age); var1.writeArrayEnd(); } } public Object read (Unpacker var1, Object var2, boolean var3) throws MessageTypeException { if (!var3 && var1.trySkipNil()) { return null ; } else { Person var4; if (var2 == null ) { var4 = new Person (); } else { var4 = (Person)var2; } var1.readArrayBegin(); if (!var1.trySkipNil()) { var4.name = (String)super .templates[0 ].read(var1, var4.name); } if (!var1.trySkipNil()) { var4.mail = (String)super .templates[1 ].read(var1, var4.mail); } var4.age = var1.readInt(); var1.readArrayEnd(); return var4; } } }
由以上代码,可看出MessagePack把java里的类作为一个Array类型进行顺序序列化为二进制数据,其只会按照字段声明顺序写入其值,而不会写入字段名,如序列化mail属性的代码为:super.templates[1].write(var1, var4.mail);
。
三、异常分析 当实体类新增字段不是最后一个字段时,且序列化端和非序列化没有同步更新实体类时,序列化端和非序列化端的Array中的字段顺序就会不一致,反序列化就会发生异常。
参考
https://msgpack.org/
https://github.com/msgpack/msgpack/blob/master/spec.md