From bb8f76d53101baa2fbba102121df8c7e3c37c1fc Mon Sep 17 00:00:00 2001 From: lzh Date: Sat, 27 Dec 2025 23:05:19 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DTCP=E4=B8=8A=E6=8A=A5?= =?UTF-8?q?=E7=A9=BAJson=E6=95=B0=E6=8D=AE=E8=A7=A3=E6=9E=90=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jt808/IotJt808DeviceMessageCodec.java | 10 +++- .../tcp/IotTcpJsonDeviceMessageCodec.java | 55 +++++++++++++++---- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/jt808/IotJt808DeviceMessageCodec.java b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/jt808/IotJt808DeviceMessageCodec.java index 684722d..01cc47e 100644 --- a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/jt808/IotJt808DeviceMessageCodec.java +++ b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/jt808/IotJt808DeviceMessageCodec.java @@ -58,7 +58,7 @@ public class IotJt808DeviceMessageCodec implements IotDeviceMessageCodec { // 根据方法名路由到不同的编码器 return switch (method) { - // === 标准物模型方法 === + // === 标准物模型方法(下行) === case "thing.service.invoke" -> encodeServiceInvoke(message, phone, flowId); // 服务调用 case "thing.property.set" -> encodePropertySet(message, phone, flowId); // 属性设置 @@ -67,8 +67,14 @@ public class IotJt808DeviceMessageCodec implements IotDeviceMessageCodec { case "jt808.platform.registerResp", "registerResp" -> encodeRegisterResp(message, phone, flowId); case "jt808.platform.textDown", "textDown" -> encodeTextDown(message, phone, flowId); + // === 上行消息方法(不应用于下行) === + case "thing.property.post", "thing.property.report" -> { + log.warn("[encode][JT808 协议不支持下行属性上报方法: {},请使用 thing.property.set 进行属性设置]", method); + yield new byte[0]; + } + default -> { - log.warn("[encode][不支持的消息方法: {}]", method); + log.warn("[encode][不支持的消息方法: {},JT808 协议仅支持下行方法: thing.service.invoke, thing.property.set]", method); yield new byte[0]; } }; diff --git a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/tcp/IotTcpJsonDeviceMessageCodec.java b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/tcp/IotTcpJsonDeviceMessageCodec.java index 75c1cf8..8fcb6c9 100644 --- a/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/tcp/IotTcpJsonDeviceMessageCodec.java +++ b/viewshanghai-module-iot/viewshanghai-module-iot-gateway/src/main/java/com/viewshanghai/module/iot/gateway/codec/tcp/IotTcpJsonDeviceMessageCodec.java @@ -95,16 +95,51 @@ public class IotTcpJsonDeviceMessageCodec implements IotDeviceMessageCodec { @SuppressWarnings("DataFlowIssue") public IotDeviceMessage decode(byte[] bytes) { String jsonStr = StrUtil.utf8Str(bytes).trim(); - TcpJsonMessage tcpJsonMessage = JsonUtils.parseObject(jsonStr, TcpJsonMessage.class); - Assert.notNull(tcpJsonMessage, "消息不能为空"); - Assert.notBlank(tcpJsonMessage.getMethod(), "消息方法不能为空"); - return IotDeviceMessage.of( - tcpJsonMessage.getId(), - tcpJsonMessage.getMethod(), - tcpJsonMessage.getParams(), - tcpJsonMessage.getData(), - tcpJsonMessage.getCode(), - tcpJsonMessage.getMsg()); + + // 快速验证是否为 JSON 格式(必须以 { 或 [ 开头) + if (StrUtil.isBlank(jsonStr)) { + throw new IllegalArgumentException("JSON 数据为空"); + } + + String trimmedJson = jsonStr.trim(); + if (!trimmedJson.startsWith("{") && !trimmedJson.startsWith("[")) { + throw new IllegalArgumentException( + String.format("不是有效的 JSON 格式,数据开头: %s", + jsonStr.length() > 20 ? jsonStr.substring(0, 20) : jsonStr)); + } + + try { + TcpJsonMessage tcpJsonMessage = JsonUtils.parseObject(jsonStr, TcpJsonMessage.class); + + // 检查解析结果 + if (tcpJsonMessage == null) { + throw new IllegalArgumentException( + String.format("JSON 解析返回 null,可能是空对象或格式错误,数据: %s", + jsonStr.length() > 100 ? jsonStr.substring(0, 100) + "..." : jsonStr)); + } + + // 检查必要字段 + if (StrUtil.isBlank(tcpJsonMessage.getMethod())) { + throw new IllegalArgumentException( + String.format("JSON 消息缺少 method 字段,数据: %s", + jsonStr.length() > 100 ? jsonStr.substring(0, 100) + "..." : jsonStr)); + } + + return IotDeviceMessage.of( + tcpJsonMessage.getId(), + tcpJsonMessage.getMethod(), + tcpJsonMessage.getParams(), + tcpJsonMessage.getData(), + tcpJsonMessage.getCode(), + tcpJsonMessage.getMsg()); + } catch (IllegalArgumentException e) { + // 重新抛出 IllegalArgumentException(已经是我们自己的错误信息) + throw e; + } catch (Exception e) { + throw new IllegalArgumentException( + String.format("JSON 解析失败,数据开头: %s,错误: %s", + jsonStr.length() > 50 ? jsonStr.substring(0, 50) : jsonStr, e.getMessage()), e); + } } }