跳至主要內容

位置上传报文解析示例

hylexus约 206 字小于 1 分钟

位置上传报文解析示例

警告

  • 808文档中定义的位置上传报文有很多字段,但是 许多厂商实现的 808协议 位置上传报文 只是原始808的一个子集
  • 本文举例用到的报文也 不是标准完整的位置上传报文,但是原理都一样。
  • 此处以 2019 版的位置上传报文为例,展示如何基于注解来解析报文。

解析报文到实体类

实体类映射关系如下:

@Data
@Accessors(chain = true)
@Jt808RequestBody
public class LocationUploadMsgV2019 {
    // (1). byte[0,4)  DWORD 报警标志
    // @RequestField(order = 1, startIndex = 0, dataType = DWORD)
    // 从 2.1.1 开始可以不再指定 `startIndex` 属性
    // 从 2.1.1 开始可以不再指定 `startIndex` 属性
    // 从 2.1.1 开始可以不再指定 `startIndex` 属性
    @RequestField(order = 1, dataType = DWORD)
    // @RequestFieldAlias.Dword(order = 1) // v2.1.1
    private long alarmFlag;

    // (2). byte[4,8) DWORD 状态
    @RequestField(order = 2, dataType = DWORD)
    // @RequestFieldAlias.Dword(order = 2)
    private int status;

    // 将上面的 status 字段的第0位取出转为 int 类型
    @SlicedFrom(sourceFieldName = "status", bitIndex = 0)
    private int accIntStatus;
    // 将上面的 status 字段的第0位取出转为 boolean 类型
    @SlicedFrom(sourceFieldName = "status", bitIndex = 0)
    private Boolean accBooleanStatus;
    // 0 北纬;1 南纬
    // 将上面的 status 字段的第2位取出转为 int 类型
    @SlicedFrom(sourceFieldName = "status", bitIndex = 2)
    private int latType;

    // (3). byte[8,12) DWORD 纬度
    @RequestField(order = 3, dataType = DWORD)
    // @RequestFieldAlias.Dword(order = 3)
    private long lat;

    // (4). byte[12,16) DWORD 经度
    @RequestField(order = 4, dataType = DWORD)
    // @RequestFieldAlias.Dword(order = 4)
    private long lng;

    // (5). byte[16,18) WORD 高度
    @RequestField(order = 5, dataType = WORD)
    // @RequestFieldAlias.Word(order = 5)
    private Integer height;

    // (6). byte[18,20) WORD 速度
    @RequestField(order = 6, dataType = WORD)
    // @RequestFieldAlias.Word(order = 6)
    private int speed;

    // (7). byte[20,22) WORD 方向
    @RequestField(order = 7, dataType = WORD)
    // @RequestFieldAlias.Word(order = 6)
    private Integer direction;

    // (8). byte[22,28) BCD[6] 时间
    @RequestField(order = 8, dataType = BCD, length = 6)
    // @RequestFieldAlias.Bcd(order = 8, length = 6)
    private String time;

    // @RequestFieldAlias.BcdDateTime(order = 8)
    // private LocalDateTime time;

    // (9). byte[28,n) 附加项列表
    // @RequestField(order = 9, dataType = LIST, lengthExpression = "#request.msgBodyLength() - 28")
    @RequestField(order = 9, dataType = LIST, lengthExpression = "#ctx.msgBodyLength() - 28")
    // @RequestFieldAlias.List(order = 9, lengthExpression = "#ctx.msgBodyLength() - 28")
    private List<ExtraItem> extraItemList;

    @Data
    public static class ExtraItem {
        // 附加信息ID
        @RequestField(order = 0, dataType = BYTE)
        // @RequestFieldAlias.Byte(order = 0)
        private int id;

        // 附加信息长度
        @RequestField(order = 1, dataType = BYTE)
        // @RequestFieldAlias.Byte(order = 1)
        private int contentLength;

        // 附加信息内容
        @RequestField(order = 3, lengthExpression = "#this.contentLength", dataType = BYTES)
        // @RequestFieldAlias.Bytes(order = 3, lengthExpression = "#this.contentLength")
        // private byte[] content; // 2.0.0 开始支持
        private ByteArrayContainer content; // 2.1.1 开始支持
        // private ByteBufContainer content; // 2.1.1 开始支持
    }
}

消息处理器如下:

@Slf4j
@Component
@Jt808RequestHandler
public class LocationMsgHandler {

    @Jt808RequestHandlerMapping(msgType = 0x0200, versions = VERSION_2019)
    public BuiltinServerCommonReplyMsg processLocationUploadMsgV2019(Jt808RequestEntity<LocationUploadMsgV2019> request) {
        log.info("LocationUpload -- V2019 -- {}", request.body());

        return BuiltinServerCommonReplyMsg.success(request.msgId(), request.flowId());
    }
}





 
 





测试

测试报文如下

7e02004086010000000001893094655200E4000000000000000101D907F2073D336C000000000000211124114808010400000026030200003001153101002504000000001404000000011504000000FA160400000000170200001803000000EA10FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02020000EF0400000000F31B017118000000000000000000000000000000000000000000000000567e

消息处理器截图如下: