diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java index 6b47d0df53..a4e93a84fd 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/config/IotGatewayConfiguration.java @@ -44,9 +44,15 @@ public class IotGatewayConfiguration { @Slf4j public static class HttpProtocolConfiguration { + @Bean(name = "httpVertx", destroyMethod = "close") + public Vertx httpVertx() { + return Vertx.vertx(); + } + @Bean - public IotHttpUpstreamProtocol iotHttpUpstreamProtocol(IotGatewayProperties gatewayProperties) { - return new IotHttpUpstreamProtocol(gatewayProperties.getProtocol().getHttp()); + public IotHttpUpstreamProtocol iotHttpUpstreamProtocol(IotGatewayProperties gatewayProperties, + @Qualifier("httpVertx") Vertx httpVertx) { + return new IotHttpUpstreamProtocol(gatewayProperties.getProtocol().getHttp(), httpVertx); } @Bean diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapUpstreamHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapUpstreamHandler.java index 4af4000d7e..d33eb464bb 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapUpstreamHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/coap/router/IotCoapUpstreamHandler.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.iot.gateway.protocol.coap.router; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrPool; import cn.hutool.core.util.ArrayUtil; @@ -93,7 +92,10 @@ public class IotCoapUpstreamHandler { // 2.2 解码消息 IotDeviceMessage message = deviceMessageService.decodeDeviceMessage(payload, productKey, deviceName); - Assert.equals(method, message.getMethod(), "method 不匹配"); + if (ObjUtil.notEqual(method, message.getMethod())) { + IotCoapUtils.respondError(exchange, CoAP.ResponseCode.BAD_REQUEST, "method 不匹配"); + return; + } // 2.3 发送消息到消息总线 deviceMessageService.sendDeviceMessage(message, productKey, deviceName, protocol.getServerId()); diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/emqx/router/IotEmqxAuthEventHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/emqx/router/IotEmqxAuthEventHandler.java index 3395d5c8ae..6b6694fd90 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/emqx/router/IotEmqxAuthEventHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/emqx/router/IotEmqxAuthEventHandler.java @@ -104,7 +104,7 @@ public class IotEmqxAuthEventHandler { JsonObject body = null; try { // 1. 解析请求体 - body = parseRequestBody(context); + body = parseEventRequestBody(context); if (body == null) { return; } @@ -153,7 +153,9 @@ public class IotEmqxAuthEventHandler { } /** - * 解析请求体 + * 解析认证接口请求体 + *

+ * 认证接口解析失败时返回 JSON 格式响应(包含 result 字段) * * @param context 路由上下文 * @return 请求体JSON对象,解析失败时返回null @@ -174,6 +176,30 @@ public class IotEmqxAuthEventHandler { } } + /** + * 解析事件接口请求体 + *

+ * 事件接口解析失败时仅返回 200 状态码,无响应体(符合 EMQX Webhook 规范) + * + * @param context 路由上下文 + * @return 请求体JSON对象,解析失败时返回null + */ + private JsonObject parseEventRequestBody(RoutingContext context) { + try { + JsonObject body = context.body().asJsonObject(); + if (body == null) { + log.info("[parseEventRequestBody][请求体为空]"); + context.response().setStatusCode(SUCCESS_STATUS_CODE).end(); + return null; + } + return body; + } catch (Exception e) { + log.error("[parseEventRequestBody][body({}) 解析请求体失败]", context.body().asString(), e); + context.response().setStatusCode(SUCCESS_STATUS_CODE).end(); + return null; + } + } + /** * 执行设备认证 * diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpUpstreamProtocol.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpUpstreamProtocol.java index a9ba930f1d..54cb2da1f4 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpUpstreamProtocol.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/IotHttpUpstreamProtocol.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpAuthHandl import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpRegisterHandler; import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpRegisterSubHandler; import cn.iocoder.yudao.module.iot.gateway.protocol.http.router.IotHttpUpstreamHandler; -import io.vertx.core.AbstractVerticle; import io.vertx.core.Vertx; import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServerOptions; @@ -24,25 +23,26 @@ import lombok.extern.slf4j.Slf4j; * @author 芋道源码 */ @Slf4j -public class IotHttpUpstreamProtocol extends AbstractVerticle { +public class IotHttpUpstreamProtocol { private final IotGatewayProperties.HttpProperties httpProperties; + private final Vertx vertx; + private HttpServer httpServer; @Getter private final String serverId; - public IotHttpUpstreamProtocol(IotGatewayProperties.HttpProperties httpProperties) { + public IotHttpUpstreamProtocol(IotGatewayProperties.HttpProperties httpProperties, Vertx vertx) { this.httpProperties = httpProperties; + this.vertx = vertx; this.serverId = IotDeviceMessageUtils.generateServerId(httpProperties.getServerPort()); } - @Override @PostConstruct public void start() { // 创建路由 - Vertx vertx = Vertx.vertx(); Router router = Router.router(vertx); router.route().handler(BodyHandler.create()); @@ -76,7 +76,6 @@ public class IotHttpUpstreamProtocol extends AbstractVerticle { } } - @Override @PreDestroy public void stop() { if (httpServer != null) { diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpAuthHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpAuthHandler.java index c6a9331ab6..148756ca8b 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpAuthHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpAuthHandler.java @@ -51,6 +51,9 @@ public class IotHttpAuthHandler extends IotHttpAbstractHandler { public CommonResult handle0(RoutingContext context) { // 1. 解析参数 JsonObject body = context.body().asJsonObject(); + if (body == null) { + throw invalidParamException("请求体不能为空"); + } String clientId = body.getString("clientId"); if (StrUtil.isEmpty(clientId)) { throw invalidParamException("clientId 不能为空"); diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterHandler.java index 525bd8487e..51459dfa26 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterHandler.java @@ -34,6 +34,9 @@ public class IotHttpRegisterHandler extends IotHttpAbstractHandler { public CommonResult handle0(RoutingContext context) { // 1. 解析参数 JsonObject body = context.body().asJsonObject(); + if (body == null) { + throw invalidParamException("请求体不能为空"); + } String productKey = body.getString("productKey"); if (StrUtil.isEmpty(productKey)) { throw invalidParamException("productKey 不能为空"); diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterSubHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterSubHandler.java index 04aad65128..32a6144b7a 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterSubHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpRegisterSubHandler.java @@ -11,6 +11,7 @@ import io.vertx.ext.web.RoutingContext; import java.util.List; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; /** @@ -44,6 +45,12 @@ public class IotHttpRegisterSubHandler extends IotHttpAbstractHandler { // 2. 解析子设备列表 JsonObject body = context.body().asJsonObject(); + if (body == null) { + throw invalidParamException("请求体不能为空"); + } + if (body.getJsonArray("params") == null) { + throw invalidParamException("params 不能为空"); + } List subDevices = JsonUtils.parseArray( body.getJsonArray("params").toString(), cn.iocoder.yudao.module.iot.core.topic.auth.IotSubDeviceRegisterReqDTO.class); diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpUpstreamHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpUpstreamHandler.java index d7d4d52ff2..5289e03a1f 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpUpstreamHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/http/router/IotHttpUpstreamHandler.java @@ -12,6 +12,8 @@ import io.vertx.ext.web.RoutingContext; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException; + /** * IoT 网关 HTTP 协议的【上行】处理器 * @@ -40,6 +42,9 @@ public class IotHttpUpstreamHandler extends IotHttpAbstractHandler { String method = context.pathParam("*").replaceAll(StrPool.SLASH, StrPool.DOT); // 2.1 解析消息 + if (context.body().buffer() == null) { + throw invalidParamException("请求体不能为空"); + } byte[] bytes = context.body().buffer().getBytes(); IotDeviceMessage message = deviceMessageService.decodeDeviceMessage(bytes, productKey, deviceName); diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/router/IotMqttUpstreamHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/router/IotMqttUpstreamHandler.java index 9dcbdd649e..d40dba447c 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/router/IotMqttUpstreamHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/mqtt/router/IotMqttUpstreamHandler.java @@ -330,15 +330,15 @@ public class IotMqttUpstreamHandler { String clientId = endpoint.clientIdentifier(); try { // 1. 解析注册参数 - IotDeviceRegisterReqDTO registerParams = parseRegisterParams(message.getParams()); - if (registerParams == null) { + IotDeviceRegisterReqDTO params = parseRegisterParams(message.getParams()); + if (params == null) { log.warn("[handleRegisterRequest][注册参数解析失败,客户端 ID: {}]", clientId); sendRegisterErrorResponse(endpoint, productKey, deviceName, message.getRequestId(), "注册参数不完整"); return; } // 2. 调用动态注册 API - CommonResult result = deviceApi.registerDevice(registerParams); + CommonResult result = deviceApi.registerDevice(params); if (result.isError()) { log.warn("[handleRegisterRequest][注册失败,客户端 ID: {},错误: {}]", clientId, result.getMsg()); sendRegisterErrorResponse(endpoint, productKey, deviceName, message.getRequestId(), result.getMsg()); @@ -348,7 +348,7 @@ public class IotMqttUpstreamHandler { // 3. 发送成功响应(包含 deviceSecret) sendRegisterSuccessResponse(endpoint, productKey, deviceName, message.getRequestId(), result.getData()); log.info("[handleRegisterRequest][注册成功,设备名: {},客户端 ID: {}]", - registerParams.getDeviceName(), clientId); + params.getDeviceName(), clientId); } catch (Exception e) { log.error("[handleRegisterRequest][注册处理异常,客户端 ID: {}]", clientId, e); sendRegisterErrorResponse(endpoint, productKey, deviceName, message.getRequestId(), "注册处理异常"); @@ -361,36 +361,27 @@ public class IotMqttUpstreamHandler { * @param params 参数对象(通常为 Map 类型) * @return 注册参数 DTO,解析失败时返回 null */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "DuplicatedCode"}) private IotDeviceRegisterReqDTO parseRegisterParams(Object params) { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 if (params instanceof Map) { Map paramMap = (Map) params; - String productKey = MapUtil.getStr(paramMap, "productKey"); - String deviceName = MapUtil.getStr(paramMap, "deviceName"); - String productSecret = MapUtil.getStr(paramMap, "productSecret"); - if (StrUtil.hasBlank(productKey, deviceName, productSecret)) { - return null; - } return new IotDeviceRegisterReqDTO() - .setProductKey(productKey) - .setDeviceName(deviceName) - .setProductSecret(productSecret); + .setProductKey(MapUtil.getStr(paramMap, "productKey")) + .setDeviceName(MapUtil.getStr(paramMap, "deviceName")) + .setProductSecret(MapUtil.getStr(paramMap, "productSecret")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceRegisterReqDTO) { return (IotDeviceRegisterReqDTO) params; } // 其他情况尝试 JSON 转换 - String jsonStr = JsonUtils.toJsonString(params); - return JsonUtils.parseObject(jsonStr, IotDeviceRegisterReqDTO.class); + return JsonUtils.convertObject(params, IotDeviceRegisterReqDTO.class); } catch (Exception e) { log.error("[parseRegisterParams][解析注册参数({})失败]", params, e); return null; diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java index 6b394206a3..4a20f46af2 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/tcp/router/IotTcpUpstreamHandler.java @@ -12,9 +12,9 @@ import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceAuthReqDTO; import cn.iocoder.yudao.module.iot.core.biz.dto.IotDeviceRespDTO; import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum; import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage; +import cn.iocoder.yudao.module.iot.core.topic.IotDeviceIdentity; import cn.iocoder.yudao.module.iot.core.topic.auth.IotDeviceRegisterReqDTO; import cn.iocoder.yudao.module.iot.core.topic.auth.IotDeviceRegisterRespDTO; -import cn.iocoder.yudao.module.iot.core.topic.IotDeviceIdentity; import cn.iocoder.yudao.module.iot.core.util.IotDeviceAuthUtils; import cn.iocoder.yudao.module.iot.gateway.codec.tcp.IotTcpBinaryDeviceMessageCodec; import cn.iocoder.yudao.module.iot.gateway.codec.tcp.IotTcpJsonDeviceMessageCodec; @@ -27,6 +27,8 @@ import io.vertx.core.buffer.Buffer; import io.vertx.core.net.NetSocket; import lombok.extern.slf4j.Slf4j; +import java.util.Map; + /** * TCP 上行消息处理器 * @@ -78,6 +80,7 @@ public class IotTcpUpstreamHandler implements Handler { // 设置消息处理器 socket.handler(buffer -> { + // TODO @AI:TODO @芋艿:这里应该有拆粘包的问题; try { processMessage(clientId, buffer, socket); } catch (Exception e) { @@ -209,15 +212,15 @@ public class IotTcpUpstreamHandler implements Handler { NetSocket socket) { try { // 1. 解析注册参数 - IotDeviceRegisterReqDTO registerParams = parseRegisterParams(message.getParams()); - if (registerParams == null) { + IotDeviceRegisterReqDTO params = parseRegisterParams(message.getParams()); + if (params == null) { log.warn("[handleRegisterRequest][注册参数解析失败,客户端 ID: {}]", clientId); sendErrorResponse(socket, message.getRequestId(), "注册参数不完整", codecType); return; } // 2. 调用动态注册 - CommonResult result = deviceApi.registerDevice(registerParams); + CommonResult result = deviceApi.registerDevice(params); if (result.isError()) { log.warn("[handleRegisterRequest][注册失败,客户端 ID: {},错误: {}]", clientId, result.getMsg()); sendErrorResponse(socket, message.getRequestId(), result.getMsg(), codecType); @@ -227,7 +230,7 @@ public class IotTcpUpstreamHandler implements Handler { // 3. 发送成功响应(包含 deviceSecret) sendRegisterSuccessResponse(socket, message.getRequestId(), result.getData(), codecType); log.info("[handleRegisterRequest][注册成功,客户端 ID: {},设备名: {}]", - clientId, registerParams.getDeviceName()); + clientId, params.getDeviceName()); } catch (Exception e) { log.error("[handleRegisterRequest][注册处理异常,客户端 ID: {}]", clientId, e); sendErrorResponse(socket, message.getRequestId(), "注册处理异常", codecType); @@ -419,30 +422,27 @@ public class IotTcpUpstreamHandler implements Handler { * @param params 参数对象(通常为 Map 类型) * @return 认证参数 DTO,解析失败时返回 null */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "DuplicatedCode"}) private IotDeviceAuthReqDTO parseAuthParams(Object params) { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 - if (params instanceof java.util.Map) { - java.util.Map paramMap = (java.util.Map) params; + if (params instanceof Map) { + Map paramMap = (Map) params; return new IotDeviceAuthReqDTO() .setClientId(MapUtil.getStr(paramMap, "clientId")) .setUsername(MapUtil.getStr(paramMap, "username")) .setPassword(MapUtil.getStr(paramMap, "password")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceAuthReqDTO) { return (IotDeviceAuthReqDTO) params; } // 其他情况尝试 JSON 转换 - String jsonStr = JsonUtils.toJsonString(params); - return JsonUtils.parseObject(jsonStr, IotDeviceAuthReqDTO.class); + return JsonUtils.convertObject(params, IotDeviceAuthReqDTO.class); } catch (Exception e) { log.error("[parseAuthParams][解析认证参数({})失败]", params, e); return null; @@ -455,28 +455,20 @@ public class IotTcpUpstreamHandler implements Handler { * @param params 参数对象(通常为 Map 类型) * @return 注册参数 DTO,解析失败时返回 null */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "DuplicatedCode"}) private IotDeviceRegisterReqDTO parseRegisterParams(Object params) { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 - if (params instanceof java.util.Map) { - java.util.Map paramMap = (java.util.Map) params; - String productKey = MapUtil.getStr(paramMap, "productKey"); - String deviceName = MapUtil.getStr(paramMap, "deviceName"); - String productSecret = MapUtil.getStr(paramMap, "productSecret"); - if (StrUtil.hasBlank(productKey, deviceName, productSecret)) { - return null; - } + if (params instanceof Map) { + Map paramMap = (Map) params; return new IotDeviceRegisterReqDTO() - .setProductKey(productKey) - .setDeviceName(deviceName) - .setProductSecret(productSecret); + .setProductKey(MapUtil.getStr(paramMap, "productKey")) + .setDeviceName(MapUtil.getStr(paramMap, "deviceName")) + .setProductSecret(MapUtil.getStr(paramMap, "productSecret")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceRegisterReqDTO) { return (IotDeviceRegisterReqDTO) params; diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/udp/router/IotUdpUpstreamHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/udp/router/IotUdpUpstreamHandler.java index f6e19e2ee5..872a615a6f 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/udp/router/IotUdpUpstreamHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/udp/router/IotUdpUpstreamHandler.java @@ -225,15 +225,15 @@ public class IotUdpUpstreamHandler { String addressKey = sessionManager.buildAddressKey(senderAddress); try { // 1. 解析注册参数 - IotDeviceRegisterReqDTO registerParams = parseRegisterParams(message.getParams()); - if (registerParams == null) { + IotDeviceRegisterReqDTO params = parseRegisterParams(message.getParams()); + if (params == null) { log.warn("[handleRegisterRequest][注册参数解析失败,来源: {}]", addressKey); sendErrorResponse(socket, senderAddress, message.getRequestId(), "注册参数不完整", codecType); return; } // 2. 调用动态注册 - CommonResult result = deviceApi.registerDevice(registerParams); + CommonResult result = deviceApi.registerDevice(params); if (result.isError()) { log.warn("[handleRegisterRequest][注册失败,来源: {},错误: {}]", addressKey, result.getMsg()); sendErrorResponse(socket, senderAddress, message.getRequestId(), result.getMsg(), codecType); @@ -243,7 +243,7 @@ public class IotUdpUpstreamHandler { // 3. 发送成功响应(包含 deviceSecret) sendRegisterSuccessResponse(socket, senderAddress, message.getRequestId(), result.getData(), codecType); log.info("[handleRegisterRequest][注册成功,设备名: {},来源: {}]", - registerParams.getDeviceName(), addressKey); + params.getDeviceName(), addressKey); } catch (Exception e) { log.error("[handleRegisterRequest][注册处理异常,来源: {}]", addressKey, e); sendErrorResponse(socket, senderAddress, message.getRequestId(), "注册处理异常", codecType); @@ -484,7 +484,6 @@ public class IotUdpUpstreamHandler { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 if (params instanceof Map) { @@ -494,15 +493,13 @@ public class IotUdpUpstreamHandler { .setUsername(MapUtil.getStr(paramMap, "username")) .setPassword(MapUtil.getStr(paramMap, "password")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceAuthReqDTO) { return (IotDeviceAuthReqDTO) params; } // 其他情况尝试 JSON 转换 - String jsonStr = JsonUtils.toJsonString(params); - return JsonUtils.parseObject(jsonStr, IotDeviceAuthReqDTO.class); + return JsonUtils.convertObject(params, IotDeviceAuthReqDTO.class); } catch (Exception e) { log.error("[parseAuthParams][解析认证参数({})失败]", params, e); return null; @@ -515,36 +512,27 @@ public class IotUdpUpstreamHandler { * @param params 参数对象(通常为 Map 类型) * @return 注册参数 DTO,解析失败时返回 null */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "DuplicatedCode"}) private IotDeviceRegisterReqDTO parseRegisterParams(Object params) { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 if (params instanceof Map) { Map paramMap = (Map) params; - String productKey = MapUtil.getStr(paramMap, "productKey"); - String deviceName = MapUtil.getStr(paramMap, "deviceName"); - String productSecret = MapUtil.getStr(paramMap, "productSecret"); - if (StrUtil.hasBlank(productKey, deviceName, productSecret)) { - return null; - } return new IotDeviceRegisterReqDTO() - .setProductKey(productKey) - .setDeviceName(deviceName) - .setProductSecret(productSecret); + .setProductKey(MapUtil.getStr(paramMap, "productKey")) + .setDeviceName(MapUtil.getStr(paramMap, "deviceName")) + .setProductSecret(MapUtil.getStr(paramMap, "productSecret")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceRegisterReqDTO) { return (IotDeviceRegisterReqDTO) params; } // 其他情况尝试 JSON 转换 - String jsonStr = JsonUtils.toJsonString(params); - return JsonUtils.parseObject(jsonStr, IotDeviceRegisterReqDTO.class); + return JsonUtils.convertObject(params, IotDeviceRegisterReqDTO.class); } catch (Exception e) { log.error("[parseRegisterParams][解析注册参数({})失败]", params, e); return null; diff --git a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/router/IotWebSocketUpstreamHandler.java b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/router/IotWebSocketUpstreamHandler.java index b4077e34d5..630246afa3 100644 --- a/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/router/IotWebSocketUpstreamHandler.java +++ b/yudao-module-iot/yudao-module-iot-gateway/src/main/java/cn/iocoder/yudao/module/iot/gateway/protocol/websocket/router/IotWebSocketUpstreamHandler.java @@ -25,6 +25,8 @@ import io.vertx.core.Handler; import io.vertx.core.http.ServerWebSocket; import lombok.extern.slf4j.Slf4j; +import java.util.Map; + /** * WebSocket 上行消息处理器 @@ -204,15 +206,16 @@ public class IotWebSocketUpstreamHandler implements Handler { private void handleRegisterRequest(String clientId, IotDeviceMessage message, ServerWebSocket socket) { try { // 1. 解析注册参数 - IotDeviceRegisterReqDTO registerParams = parseRegisterParams(message.getParams()); - if (registerParams == null) { + IotDeviceRegisterReqDTO params = parseRegisterParams(message.getParams()); + if (params == null + || StrUtil.hasEmpty(params.getProductKey(), params.getDeviceName(), params.getProductSecret())) { log.warn("[handleRegisterRequest][注册参数解析失败,客户端 ID: {}]", clientId); sendErrorResponse(socket, message.getRequestId(), "注册参数不完整"); return; } // 2. 调用动态注册 - CommonResult result = deviceApi.registerDevice(registerParams); + CommonResult result = deviceApi.registerDevice(params); if (result.isError()) { log.warn("[handleRegisterRequest][注册失败,客户端 ID: {},错误: {}]", clientId, result.getMsg()); sendErrorResponse(socket, message.getRequestId(), result.getMsg()); @@ -222,7 +225,7 @@ public class IotWebSocketUpstreamHandler implements Handler { // 3. 发送成功响应(包含 deviceSecret) sendRegisterSuccessResponse(socket, message.getRequestId(), result.getData()); log.info("[handleRegisterRequest][注册成功,客户端 ID: {},设备名: {}]", - clientId, registerParams.getDeviceName()); + clientId, params.getDeviceName()); } catch (Exception e) { log.error("[handleRegisterRequest][注册处理异常,客户端 ID: {}]", clientId, e); sendErrorResponse(socket, message.getRequestId(), "注册处理异常"); @@ -384,31 +387,27 @@ public class IotWebSocketUpstreamHandler implements Handler { * @param params 参数对象(通常为 Map 类型) * @return 认证参数 DTO,解析失败时返回 null */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "DuplicatedCode"}) private IotDeviceAuthReqDTO parseAuthParams(Object params) { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 - if (params instanceof java.util.Map) { - java.util.Map paramMap = (java.util.Map) params; + if (params instanceof Map) { + Map paramMap = (Map) params; return new IotDeviceAuthReqDTO() .setClientId(MapUtil.getStr(paramMap, "clientId")) .setUsername(MapUtil.getStr(paramMap, "username")) .setPassword(MapUtil.getStr(paramMap, "password")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceAuthReqDTO) { return (IotDeviceAuthReqDTO) params; } // 其他情况尝试 JSON 转换 - // TODO @芋艿:要不要优化下; - String jsonStr = JsonUtils.toJsonString(params); - return JsonUtils.convertObject(jsonStr, IotDeviceAuthReqDTO.class); + return JsonUtils.convertObject(params, IotDeviceAuthReqDTO.class); } catch (Exception e) { log.error("[parseAuthParams][解析认证参数({})失败]", params, e); return null; @@ -426,31 +425,22 @@ public class IotWebSocketUpstreamHandler implements Handler { if (params == null) { return null; } - try { // 参数默认为 Map 类型,直接转换 - if (params instanceof java.util.Map) { - java.util.Map paramMap = (java.util.Map) params; - String productKey = MapUtil.getStr(paramMap, "productKey"); - String deviceName = MapUtil.getStr(paramMap, "deviceName"); - String productSecret = MapUtil.getStr(paramMap, "productSecret"); - if (StrUtil.hasBlank(productKey, deviceName, productSecret)) { - return null; - } + if (params instanceof Map) { + Map paramMap = (Map) params; return new IotDeviceRegisterReqDTO() - .setProductKey(productKey) - .setDeviceName(deviceName) - .setProductSecret(productSecret); + .setProductKey(MapUtil.getStr(paramMap, "productKey")) + .setDeviceName(MapUtil.getStr(paramMap, "deviceName")) + .setProductSecret(MapUtil.getStr(paramMap, "productSecret")); } - // 如果已经是目标类型,直接返回 if (params instanceof IotDeviceRegisterReqDTO) { return (IotDeviceRegisterReqDTO) params; } // 其他情况尝试 JSON 转换 - String jsonStr = JsonUtils.toJsonString(params); - return JsonUtils.parseObject(jsonStr, IotDeviceRegisterReqDTO.class); + return JsonUtils.convertObject(params, IotDeviceRegisterReqDTO.class); } catch (Exception e) { log.error("[parseRegisterParams][解析注册参数({})失败]", params, e); return null;