fix: 修复bug-Caused by: java.lang.RuntimeException: JT808 消息解码失败: null
All checks were successful
aiot-platform CI/CD / build-and-deploy (push) Successful in 7m28s
All checks were successful
aiot-platform CI/CD / build-and-deploy (push) Successful in 7m28s
This commit is contained in:
@@ -100,34 +100,74 @@ public class IotJt808DeviceMessageCodec implements IotDeviceMessageCodec {
|
||||
|
||||
/**
|
||||
* 将 JT808 数据包转换为 IotDeviceMessage
|
||||
*
|
||||
* @param dataPack JT808 数据包
|
||||
* @return IotDeviceMessage 消息对象
|
||||
*/
|
||||
private IotDeviceMessage convertToIotDeviceMessage(Jt808DataPack dataPack) {
|
||||
Jt808DataPack.PackHead head = dataPack.getPackHead();
|
||||
int msgId = head.getId();
|
||||
Assert.notNull(dataPack, "JT808 数据包不能为空");
|
||||
|
||||
// 生成消息ID(使用流水号作为标识)
|
||||
String messageId = head.getTerminalPhone() + "_" + head.getFlowId();
|
||||
Jt808DataPack.PackHead head = dataPack.getPackHead();
|
||||
Assert.notNull(head, "JT808 数据包头部不能为空");
|
||||
|
||||
int msgId = head.getId();
|
||||
String terminalPhone = head.getTerminalPhone();
|
||||
int flowId = head.getFlowId();
|
||||
|
||||
// 生成请求ID(用于追踪和关联,格式:终端手机号_流水号_时间戳)
|
||||
// 添加时间戳确保唯一性,避免同一终端同一流水号重复
|
||||
String requestId = String.format("%s_%d_%d", terminalPhone, flowId, System.currentTimeMillis());
|
||||
|
||||
// 根据消息ID确定物模型标准方法名
|
||||
String method = getStandardMethodName(msgId);
|
||||
|
||||
// 解析消息参数
|
||||
Object params = parseMessageParams(dataPack, msgId);
|
||||
|
||||
// 构建元数据(保留在 params 中,用于调试和追踪)
|
||||
// 构建元数据并添加到 params 中(用于调试和追踪)
|
||||
params = enrichParamsWithMetadata(params, msgId, terminalPhone, flowId, head.getEncryptionType());
|
||||
|
||||
// 创建 IotDeviceMessage(of 方法会自动生成 id 和 reportTime)
|
||||
return IotDeviceMessage.of(requestId, method, params, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为参数对象添加元数据
|
||||
*
|
||||
* @param params 原始参数对象
|
||||
* @param msgId JT808 消息ID
|
||||
* @param terminalPhone 终端手机号
|
||||
* @param flowId 流水号
|
||||
* @param encryptionType 加密类型
|
||||
* @return 包含元数据的参数对象
|
||||
*/
|
||||
private Object enrichParamsWithMetadata(Object params, int msgId, String terminalPhone,
|
||||
int flowId, int encryptionType) {
|
||||
// 构建元数据 Map
|
||||
Map<String, Object> metadata = new HashMap<>(4);
|
||||
metadata.put("jt808MsgId", String.format("0x%04X", msgId));
|
||||
metadata.put("terminalPhone", terminalPhone);
|
||||
metadata.put("flowId", flowId);
|
||||
metadata.put("encryptionType", encryptionType);
|
||||
|
||||
// 如果 params 是 Map 类型,则添加元数据
|
||||
if (params instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> paramsMap = (Map<String, Object>) params;
|
||||
Map<String, Object> metadata = new HashMap<>();
|
||||
metadata.put("jt808MsgId", String.format("0x%04X", msgId));
|
||||
metadata.put("terminalPhone", head.getTerminalPhone());
|
||||
metadata.put("flowId", head.getFlowId());
|
||||
metadata.put("encryptionType", head.getEncryptionType());
|
||||
paramsMap.put("_metadata", metadata);
|
||||
|
||||
// 创建新的可变 Map,确保可以添加元数据
|
||||
// 注意:某些解析方法可能返回不可变的 Map(如 Map.of()),需要转换为可变 Map
|
||||
Map<String, Object> enrichedParams = new HashMap<>(paramsMap);
|
||||
enrichedParams.put("_metadata", metadata);
|
||||
return enrichedParams;
|
||||
}
|
||||
|
||||
// 创建 IotDeviceMessage
|
||||
IotDeviceMessage message = IotDeviceMessage.of(messageId, method, params, null, null, null);
|
||||
message.setReportTime(LocalDateTime.now());
|
||||
return message;
|
||||
// 如果 params 不是 Map,则包装为包含元数据的 Map
|
||||
// 保留原始 params 在 _data 字段中
|
||||
Map<String, Object> wrapper = new HashMap<>(2);
|
||||
wrapper.put("_data", params);
|
||||
wrapper.put("_metadata", metadata);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user