ProtoStuff沒法反序列化Deprecated註解成員問題記錄

在開發過程當中,遇到一個鬼畜的問題,在DO的某個成員上添加@Deprecated註解以後,經過ProtoStuff反序列化獲得的DO中,這個成員一直爲null;花了很多時間才定位這個問題,特此記錄一下java

原文 ProtoStuff沒法反序列化Deprecated註解成員問題記錄

I. 全程實錄

1. 環境相關

原項目中使用protostuff做爲POJO序列化工具,對應的版本爲git

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

2. 場景復現

寫了一個簡單的demo,咱們在POJO中添加一個擁有刪除註解的成員,而後查看下反序列化結果github

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class BDO implements Serializable {
    private String a;
    @Deprecated
    private String b;
}

@Test
public void testSer() {
    BDO b = new BDO("10", "20");
    Schema<BDO> schema = RuntimeSchema.getSchema(BDO.class);

    LinkedBuffer buffer = LinkedBuffer.allocate(512);
    final byte[] protostuff;
    try {
        protostuff = ProtostuffIOUtil.toByteArray(b, schema, buffer);
    } finally {
        buffer.clear();
    }

    // deser
    BDO fooParsed = schema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, fooParsed, schema);
    System.out.println(fooParsed);
}

下面是測試輸出,能夠看到反序列化的結果中,b爲nullapi

image

天然就會有個疑問,是在序列化的時候直接丟掉了這個成員信息呢,仍是反序列化的時候跳過了這個成員?工具

咱們新增一個POJO,與BDO的成員相似,只是沒有@Deprecated註解學習

@Data
@NoArgsConstructor
@AllArgsConstructor
public static class NDO implements Serializable {
    private String a;
    private String b;
}

而後驗證下BDO序列化的結果,經過反序列化爲NDO對象,若是b成員有值,說明在序列化的時候並無丟掉;測試

@Test
public void testSer2() {
    BDO b = new BDO("10", "20");
    Schema<BDO> schema = RuntimeSchema.getSchema(BDO.class);

    LinkedBuffer buffer = LinkedBuffer.allocate(512);
    final byte[] protostuff;
    try {
        protostuff = ProtostuffIOUtil.toByteArray(b, schema, buffer);
    } finally {
        buffer.clear();
    }

    Schema<NDO> nSchema = RuntimeSchema.getSchema(NDO.class);
    NDO ndo = nSchema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, ndo, nSchema);
    System.out.println(ndo);
}

從下面的輸出能夠看到,反序列化不出來,在序列化的時候就已經丟掉了ui

image

接着咱們再驗證下NDO序列化的結果,由於沒有Deprecated註解,反序列化爲NDO對象時,應該是齊全的,那麼反序列化爲BDO呢spa

@Test
public void testSer3() {
    NDO n = new NDO("10", "20");
    Schema<NDO> schema = RuntimeSchema.getSchema(NDO.class);

    LinkedBuffer buffer = LinkedBuffer.allocate(512);
    final byte[] protostuff;
    try {
        protostuff = ProtostuffIOUtil.toByteArray(n, schema, buffer);
    } finally {
        buffer.clear();
    }

    NDO ans = schema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, ans, schema);
    System.out.println(ans);

    Schema<BDO> bSchema = RuntimeSchema.getSchema(BDO.class);
    BDO bdo = bSchema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, bdo, bSchema);
    System.out.println(bdo);
}

從下面的輸出能夠看出,反序列化時,成員上有@Deprecated註解時,也沒法獲取正確的結果設計

image

3. 兼容方案

查了下protostuf的相關文檔,我的感受它的設計理念就是認爲加了這個刪除註解,就沒有必要繼續存在了,就直接給忽略了。那麼我但願加上了這個註解的能夠被序列化/反序列化,有辦法麼?

查看api的時候,發如今建立Schema的時候,有個方法io.protostuff.runtime.RuntimeSchema#createFrom(java.lang.Class<T>, java.util.Map<java.lang.String,java.lang.String>, io.protostuff.runtime.IdStrategy), 能夠指定成員列表

因而咱們就有了一個猥瑣的兼容方式

@Test
public void testSer() {
    BDO b = new BDO("10", "20");
    Map<String, String> map = new HashMap<>();
    map.put("a", "a");
    map.put("b", "b");
    Schema<BDO> schema = RuntimeSchema.createFrom(BDO.class, map, RuntimeEnv.ID_STRATEGY);
    //        Schema<BDO> schema = RuntimeSchema.createFrom(BDO.class, new String[]{}, RuntimeEnv.ID_STRATEGY);

    LinkedBuffer buffer = LinkedBuffer.allocate(512);
    final byte[] protostuff;
    try {
        protostuff = ProtostuffIOUtil.toByteArray(b, schema, buffer);
    } finally {
        buffer.clear();
    }

    // deser
    BDO fooParsed = schema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, fooParsed, schema);
    System.out.println(fooParsed);
}

測試結果以下,反序列化的實例中有相應的數據了

image

4. 小結

遵循ProtoStuff的使用規範,若是一個成員上有註解@Deprecated,那麼這個成員的數據將不會被序列化和反序列化

II. 其餘

1. 一灰灰Bloghttps://liuyueyi.github.io/he...

一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛

2. 聲明

盡信書則不如,已上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

3. 掃描關注

一灰灰blog

QrCode

知識星球

goals

相關文章
相關標籤/搜索