Skip to content

calcCheckCode & calcLength 属性详解

ray.zh edited this page Feb 22, 2024 · 10 revisions

V2.1.0新增属性

这两个属性都是为了解决校验和计算与长度计算问题设计。 值得一提的是,整个数据结构中, 目前 calcCheckCode & calcLength 只能使用一次,即一条报文只能存在一个长度字段和一个校验和字段。

在序列化时, magic-byte 将会进行以下操作:

  • 自动将总字节数填充于 calcLength = true 的属性中
  • 自动调用校验和计算函数, 并将结果填充于 calcCheckCode = true 的属性中

在反序列化且类启用严格模式strict=true时, magic-byte将会进行以下操作:

  • 校验 calcLength = true 的值, 如不匹配则抛出 InvalidLengthException
  • 校验 calcCheckCode = true 的值, 如不匹配则抛出 InvalidCheckCodeException

代码示例:

@MagicClass
public class Office {
    @MagicField(order = 1)
    private int head;
    // calcLength = true 时, 序列化后此值将会自动填充, 只能标记一次
    @MagicField(order = 3, calcLength = true)
    private int length;
    @MagicField(order = 5, size = 10)
    private String name;
    @MagicField(order = 7, size = 10)
    private String addr;
    @MagicField(order = 9, size = 5, dynamicSize = true)
    private List<Staff> staffs;
    // calcCheckCode = true 时, 序列化后此值将会自动填充, 只能标记一次
    @MagicField(order = 13, calcCheckCode = true)
    private byte checkCode;
}

public class TestFunctional {

    /**
     * 校验和计算函数定义, 请保持和此处函数定义一致
     * 
     * 序列化时: data数据中包含所有已序列化的数据(包括 calcLength 也已经调用并序列化)
     * 反序列化时: data数据为传入数据的副本
     * @param data 
     * @return  返回计算结果
     */
    public static byte[] checker(byte[] data) {
        return new byte[]{0x33, 0x41};
    }
}

public static void main(String[] args) {
    // 全局配置校验和计算方法
    MagicByte.configMagicChecker(TestFunctional::checker);
    
    // 可以序列化时单独传入校验和计算函数, 如没有传入则使用全局配置, 未配置则忽略
    ByteBuffer unpack = MagicByte.unpack(officeStrict, TestFunctional::checker2);
    // 可以反序列化时单独传入校验和计算函数, 如没有传入则使用全局配置, 未配置则忽略
    OfficeStrict officeStrict2 = MagicByte.pack(unpack.array(), OfficeStrict.class, TestFunctional::checker2);
}

请注意: calcCheckCode仅适用于 byte,short,int,long; calcLength仅适用于byte,short,int