使用Protocol Buffer反序列化踩坑

694 阅读1分钟
  • 问题产生背景

        Protocol Buffer存储方式:T-L(可选)-V

        1. Tag

            a. Tag=字段数据类型(wire_type)+标识号(field_number)

            b. 占用一个字节的长度(如果标示号超过了16,则占用多一个字节的位子)

            c. 反序列化时, Protocol Buffer根据Tag将Value对应于消息中的字段

        2. Value(filed_value)

  • 问题分析

    public class Before {
    private Integer A;
    private String B;
    private BigDecimal C; }

    public class After {
    private Integer A;
    private String B;
    private String D; private BigDecimal C; }

项目A中最初在Redis中存放的是对象Before, 由于开发新需求, 需要新增字段D, 后续在Redis中存放的是对象After。新功能上线之后,项目A查询历史数据时反序列化字段错位, 即D的值是之前存储的C的值, 而C对应的值是空。因为Protocol Buffer序列化的时候没有存储字段名称(T里面只有filed_number),所以反序列化时也只是按照顺序set值。

  • 解决方案

    public class After {
    private Integer A;
    private String B;
    private BigDecimal C;
    // 新增的字段一定要放到对象的末尾 private String D; }

在此建议,无论之后开发中使用的是哪种序列化方式,对象新增字段的时候一定要追加到末尾!