位置上传报文解析示例
约 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
消息处理器截图如下: