1. 程式人生 > >網路傳輸資料序列化工具Protostuff

網路傳輸資料序列化工具Protostuff

一直在物色比較好用的網路傳輸資料序列化工具,看了諸如marshalling,protobuff等,但是均有一個共同特點,使用起來異常繁雜,有沒有比較好用同時效能又不會太差的元件呢?答案當然是有的,那就是基於protobuff改造的protostuff,它擁有良好效能的同時,又免去了生成描述檔案的煩惱,可謂是趁手利器。

來看看具體的使用方式吧。

首先,引入maven依賴如下:

<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-core</artifactId>
    <version>1.4.4</version>
</dependency>
<dependency>
    <groupId>io.protostuff</groupId>
    <artifactId>protostuff-runtime</artifactId>
    <version>1.4.4</version>
</dependency>

之後,編寫序列化工具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
; Class<SerializeData> serializeDataClass = (Class<SerializeData>) serializeData.getClass(); LinkedBuffer linkedBuffer = LinkedBuffer.allocate(1024 * 4); try { Schema<SerializeData> 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> T deserialize(byte[] data, Class<T> clazz) { try { Schema<SerializeData> 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");

        List<String> list = 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<Teacher> 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 List<String> records;
    private List<Teacher> 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<String> getRecords() {
        return records;
    }

    public void setRecords(List<String> records) {
        this.records = records;
    }

    public List<Teacher> getTeachers() {
        return teachers;
    }

    public void setTeachers(List<Teacher> 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}

可以看到,這種相對來說比較複雜的結構的序列化和反序列化,還是挺得心應手的。

 

參考:序列化利器-protostuff