跳至主要內容

扁平化写法示例

hylexus大约 1 分钟示例编码解码JT/T 808

扁平化写法示例

提示

  • 在阅读本文之前,建议先阅读 协议格式说明
  • 所谓的 扁平化写法 就是不用单独封装 HeaderBody,而是直接将 HeaderBody 的数据写在同一个实体类中

解码

实体类定义

Rust 命名风格
@Setter
@Getter
@ToString
public class RustStyleDebugEntity02ForDecode {

    // region 消息头
    // byte[0-2) 	消息ID word(16)
    @Preset.RustStyle.u16
    private int msgId;

    // byte[2-4) 	消息体属性 word(16)
    @Preset.RustStyle.u16
    private int msgBodyProps;

    // byte[4]     协议版本号
    @Preset.RustStyle.u8
    private byte protocolVersion;

    // byte[5-15) 	终端手机号或设备ID bcd[10]
    @Preset.RustStyle.str(charset = "bcd_8421", length = 10)
    private String terminalId;

    // byte[15-17) 	消息流水号 word(16)
    @Preset.RustStyle.u16
    private int msgSerialNo;

    // byte[17-21) 	消息包封装项
    @Preset.RustStyle.u32(condition = "hasSubPackage()")
    private Long subPackageInfo;
    // endregion 消息头

    // region 消息体
    // 报警标志  DWORD(4)
    @Preset.RustStyle.u32
    private long alarmFlag;

    // 状态  DWORD(4)
    @Preset.RustStyle.u32
    private long status;

    // 纬度  DWORD(4)
    @Preset.RustStyle.u32
    private long latitude;

    // 经度  DWORD(4)
    @Preset.RustStyle.u32
    private long longitude;

    // 高程  WORD(2)
    @Preset.RustStyle.u16
    private int altitude;

    // 高程  WORD(2)
    @Preset.RustStyle.u16
    private int speed;

    // 方向  WORD(2)
    @Preset.RustStyle.u16
    private int direction;

    // 时间  BCD[6] yyMMddHHmmss
    @Preset.RustStyle.str(charset = "bcd_8421", length = 6)
    private String time;

    // 长度:消息体长度减去前面的 28 字节
    @Preset.RustStyle.list(lengthExpression = "msgBodyLength() - 28")
    private List<ExtraItem> extraItems;
    // endregion 消息体

    // 校验码
    @Preset.RustStyle.i8
    private byte checkSum;

    // bit[0-9] 0000,0011,1111,1111(3FF)(消息体长度)
    public int msgBodyLength() {
        return msgBodyProps & 0x3ff;
    }

    // bit[13] 0010,0000,0000,0000(2000)(是否有子包)
    public boolean hasSubPackage() {
        // return ((msgBodyProperty & 0x2000) >> 13) == 1;
        return (msgBodyProps & 0x2000) > 0;
    }


    @Setter
    @Getter
    @ToString
    public static class ExtraItem {
        // 附加信息ID   BYTE(1~255)
        @Preset.RustStyle.u8
        private short id;
        // 附加信息长度   BYTE(1~255)
        @Preset.RustStyle.u8
        private short contentLength;
        // 附加信息内容  BYTE[N]
        @Preset.RustStyle.byte_array(lengthExpression = "getContentLength()")
        private byte[] content;

        public ExtraItem() {
        }

        public ExtraItem(short id, short length, byte[] content) {
            this.id = id;
            this.contentLength = length;
            this.content = content;
        }
    }
}

反序列化

public class EntityDecodeTest {

    @Test
    void testDecode() {
        final EntityCodec entityCodec = new EntityCodec();

        // buffer 中存储的是要反序列化的数据(这里写死用来演示)
        final String hexString = "0200402a01000000000139111122220063000000580000006f01dc9a0707456246231d029a005a240322222633010400001a0a02020058030200595b";
        final ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer().writeBytes(XtreamBytes.decodeHex(hexString));

        try {
            final RustStyleDebugEntity02ForDecode entity = entityCodec.decode(RustStyleDebugEntity02ForDecode.class, buffer);
            System.out.println(entity);
        } finally {
            buffer.release();
        }
    }
}











 


 



编码

实体类定义

Rust 命名风格
@Setter
@Getter
@ToString
public class RustStyleDebugEntity02ForEncode {

    // region 消息头
    // byte[0-2) 	消息ID word(16)
    @Preset.RustStyle.u16
    private int msgId;

    // byte[2-4) 	消息体属性 word(16)
    @Preset.RustStyle.u16
    private int msgBodyProps;

    // byte[4]     协议版本号
    @Preset.RustStyle.u8
    private byte protocolVersion;

    // byte[5-15) 	终端手机号或设备ID bcd[10]
    @Preset.RustStyle.str(charset = "bcd_8421")
    private String terminalId;

    // byte[15-17) 	消息流水号 word(16)
    @Preset.RustStyle.u16
    private int msgSerialNo;

    // byte[17-21) 	消息包封装项
    @Preset.RustStyle.u32
    private Long subPackageInfo;
    // endregion 消息头

    // region 消息体
    // 报警标志  DWORD(4)
    @Preset.RustStyle.u32
    private long alarmFlag;

    // 状态  DWORD(4)
    @Preset.RustStyle.u32
    private long status;

    // 纬度  DWORD(4)
    @Preset.RustStyle.u32
    private long latitude;

    // 经度  DWORD(4)
    @Preset.RustStyle.u32
    private long longitude;

    // 高程  WORD(2)
    @Preset.RustStyle.u16
    private int altitude;

    // 高程  WORD(2)
    @Preset.RustStyle.u16
    private int speed;

    // 方向  WORD(2)
    @Preset.RustStyle.u16
    private int direction;

    // 时间  BCD[6] yyMMddHHmmss
    @Preset.RustStyle.str(charset = "bcd_8421")
    private String time;

    @Preset.RustStyle.list
    private List<ExtraItem> extraItems;
    // endregion 消息体

    // 校验码
    @Preset.RustStyle.i8
    private byte checkSum;


    @Setter
    @Getter
    @ToString
    public static class ExtraItem {
        // 附加信息ID   BYTE(1~255)
        @Preset.RustStyle.u8
        private short id;
        // 附加信息长度   BYTE(1~255)
        @Preset.RustStyle.u8
        private short contentLength;
        // 附加信息内容  BYTE[N]
        @Preset.RustStyle.byte_array(lengthExpression = "getLength()")
        private byte[] content;

        public ExtraItem() {
        }

        public ExtraItem(short id, short contentLength, byte[] content) {
            this.id = id;
            this.contentLength = contentLength;
            this.content = content;
        }
    }
}

序列化

public class EntityEncodeTest {

    @Test
    void testEncode() {
        final EntityCodec entityCodec = new EntityCodec();

        final ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
        try {
            final RustStyleDebugEntity02ForEncode instance = new RustStyleDebugEntity02ForEncode();
            // TODO 省略属性赋值
            // instance.setXxx(someValue);
            // instance.setMsgId(someValue);
            // ...

            // 将 instance 的数据序列化到 buffer 中
            entityCodec.encode(instance, buffer);
            // 使用 buffer
            System.out.println(ByteBufUtil.hexDump(buffer));
        } finally {
            buffer.release();
        }
    }
}