一直在物色比较好用的网络传输数据序列化工具,看了诸如marshalling,protobuff等,但是均有一个共同特点,使用起来异常繁杂,有没有比较好用同时性能又不会太差的组件呢?答案当然是有的,那就是基于protobuff改造的protostuff,它拥有良好性能的同时,又免去了生成描述文件的烦恼,可谓是趁手利器。
来看看具体的使用方式吧。
首先,引入maven依赖如下:
io.protostuff protostuff-core 1.4.4 io.protostuff protostuff-runtime 1.4.4
之后,编写序列化工具Util:
public class SerializeUtil { private static class SerializeData{ private Object target; } @SuppressWarnings("unchecked") public static byte[] serialize(Object object) { SerializeData serializeData = new SerializeData(); serializeData.target = object; ClassserializeDataClass = (Class ) serializeData.getClass(); LinkedBuffer linkedBuffer = LinkedBuffer.allocate(1024 * 4); try { Schema schema = RuntimeSchema.getSchema(serializeDataClass); return ProtostuffIOUtil.toByteArray(serializeData, schema, linkedBuffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { linkedBuffer.clear(); } } @SuppressWarnings("unchecked") public static T deserialize(byte[] data, Class clazz) { try { Schema schema = RuntimeSchema.getSchema(SerializeData.class); SerializeData serializeData = schema.newMessage(); ProtostuffIOUtil.mergeFrom(data, serializeData, schema); return (T) serializeData.target; } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } }}
需要注意的是RuntimeSchema.getSchema这块代码,通过翻看源码可以知道,里面已经放置了一个缓存map帮我们缓存生成的内容,所以不需要自己再加缓存了。
由于protostuff目前不支持序列化list等对象,所以需要使用普通的POJO包装一下。
最后,来写一个测试吧:
public static void main(String...args) throws Exception { User user = new User(); user.setUserId(123456); user.setAddress("I am a good boy"); user.setNote("this is test"); Listlist = new ArrayList<>(); list.add("record1"); list.add("record2"); list.add("record3"); user.setRecords(list); Teacher teacher1 = new Teacher(); teacher1.setName("语文老师"); Teacher teacher2 = new Teacher(); teacher2.setName("数学老师"); List teachers = new ArrayList<>(); teachers.add(teacher1); teachers.add(teacher2); user.setTeachers(teachers); byte[] b = serialize(user); User rst = deserialize(b, User.class); System.out.println(JSON.toJSONString(rst)); }
class User { private Integer userId; private String address; private String note; private Listrecords; private List teachers; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getNote() { return note; } public void setNote(String note) { this.note = note; } public List getRecords() { return records; } public void setRecords(List records) { this.records = records; } public List getTeachers() { return teachers; } public void setTeachers(List teachers) { this.teachers = teachers; }}class Teacher{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}
最终的运行结果如下:
{ "address":"I am a good boy","note":"this is test","records":["record1","record2","record3"],"teachers":[{ "name":"语文老师"},{ "name":"数学老师"}],"userId":123456}
可以看到,这种相对来说比较复杂的结构的序列化和反序列化,还是挺得心应手的。
参考: