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

相关文章
相关标签/搜索