mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	feat: 【IoT 物联网】新增简单类型处理器配置和处理器,优化 JSON 解析问题
This commit is contained in:
		| @ -0,0 +1,33 @@ | ||||
| package cn.iocoder.yudao.module.iot.framework.mybatis.config; | ||||
|  | ||||
| import cn.iocoder.yudao.module.iot.framework.mybatis.handler.SimpleObjectTypeHandler; | ||||
| import jakarta.annotation.PostConstruct; | ||||
| import jakarta.annotation.Resource; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.apache.ibatis.session.SqlSessionFactory; | ||||
| import org.apache.ibatis.type.TypeHandlerRegistry; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
|  | ||||
| /** | ||||
|  * 简单类型处理器配置 | ||||
|  * 注册自定义的类型处理器,避免 JSON 解析错误 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| @Slf4j | ||||
| @Configuration | ||||
| public class SimpleTypeHandlerConfig { | ||||
|  | ||||
|     @Resource | ||||
|     private SqlSessionFactory sqlSessionFactory; | ||||
|  | ||||
|     @PostConstruct | ||||
|     public void registerTypeHandlers() { | ||||
|         TypeHandlerRegistry registry = sqlSessionFactory.getConfiguration().getTypeHandlerRegistry(); | ||||
|  | ||||
|         // 注册简单的 Object 类型处理器,避免 JSON 解析问题 | ||||
|         registry.register(java.lang.Object.class, new SimpleObjectTypeHandler()); | ||||
|  | ||||
|         log.info("简单类型处理器注册完成,避免 JSON 解析错误"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,39 @@ | ||||
| package cn.iocoder.yudao.module.iot.framework.mybatis.handler; | ||||
|  | ||||
| import org.apache.ibatis.type.BaseTypeHandler; | ||||
| import org.apache.ibatis.type.JdbcType; | ||||
|  | ||||
| import java.sql.CallableStatement; | ||||
| import java.sql.PreparedStatement; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
|  | ||||
| /** | ||||
|  * 简单的 Object 类型处理器 | ||||
|  * 直接返回字符串,避免 JSON 解析问题 | ||||
|  * | ||||
|  * @author 芋道源码 | ||||
|  */ | ||||
| public class SimpleObjectTypeHandler extends BaseTypeHandler<Object> { | ||||
|  | ||||
|     @Override | ||||
|     public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) | ||||
|             throws SQLException { | ||||
|         ps.setString(i, parameter.toString()); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Object getNullableResult(ResultSet rs, String columnName) throws SQLException { | ||||
|         return rs.getString(columnName); // 直接返回字符串 | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException { | ||||
|         return rs.getString(columnIndex); // 直接返回字符串 | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { | ||||
|         return cs.getString(columnIndex); // 直接返回字符串 | ||||
|     } | ||||
| } | ||||
| @ -66,8 +66,15 @@ | ||||
|         DESCRIBE product_property_${productId} | ||||
|     </select> | ||||
|  | ||||
|     <resultMap id="IotDevicePropertyRespVOMap" | ||||
|                type="cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO"> | ||||
|         <result property="value" column="value" | ||||
|                 typeHandler="cn.iocoder.yudao.module.iot.framework.mybatis.handler.SimpleObjectTypeHandler"/> | ||||
|         <result property="updateTime" column="update_time" javaType="java.lang.Long"/> | ||||
|     </resultMap> | ||||
|  | ||||
|     <select id="selectListByHistory" | ||||
|             resultType="cn.iocoder.yudao.module.iot.controller.admin.device.vo.property.IotDevicePropertyRespVO"> | ||||
|             resultMap="IotDevicePropertyRespVOMap"> | ||||
|         SELECT ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} AS `value`, ts AS update_time | ||||
|         FROM device_property_${reqVO.deviceId} | ||||
|         WHERE ${@cn.hutool.core.util.StrUtil@toUnderlineCase(reqVO.identifier)} IS NOT NULL | ||||
|  | ||||
| @ -68,7 +68,13 @@ public class IotMqttUpstreamHandler { | ||||
|  | ||||
|         log.info("[handle][设备认证成功,建立连接,客户端 ID: {},用户名: {}]", clientId, username); | ||||
|  | ||||
|         // 2. 设置异常和关闭处理器 | ||||
|         // 2. 设置心跳处理器(监听客户端的 PINGREQ 消息) | ||||
|         endpoint.pingHandler(v -> { | ||||
|             log.debug("[handle][收到客户端心跳,客户端 ID: {}]", clientId); | ||||
|             // Vert.x 会自动发送 PINGRESP 响应,无需手动处理 | ||||
|         }); | ||||
|  | ||||
|         // 3. 设置异常和关闭处理器 | ||||
|         endpoint.exceptionHandler(ex -> { | ||||
|             log.warn("[handle][连接异常,客户端 ID: {},地址: {}]", clientId, connectionManager.getEndpointAddress(endpoint)); | ||||
|             cleanupConnection(endpoint); | ||||
| @ -77,7 +83,7 @@ public class IotMqttUpstreamHandler { | ||||
|             cleanupConnection(endpoint); | ||||
|         }); | ||||
|  | ||||
|         // 3. 设置消息处理器 | ||||
|         // 4. 设置消息处理器 | ||||
|         endpoint.publishHandler(message -> { | ||||
|             try { | ||||
|                 processMessage(clientId, message.topicName(), message.payload().getBytes()); | ||||
| @ -100,7 +106,7 @@ public class IotMqttUpstreamHandler { | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         // 4. 设置订阅处理器 | ||||
|         // 5. 设置订阅处理器 | ||||
|         endpoint.subscribeHandler(subscribe -> { | ||||
|             // 提取主题名称列表用于日志显示 | ||||
|             List<String> topicNames = subscribe.topicSubscriptions().stream() | ||||
| @ -115,22 +121,22 @@ public class IotMqttUpstreamHandler { | ||||
|             endpoint.subscribeAcknowledge(subscribe.messageId(), grantedQoSLevels); | ||||
|         }); | ||||
|  | ||||
|         // 5. 设置取消订阅处理器 | ||||
|         // 6. 设置取消订阅处理器 | ||||
|         endpoint.unsubscribeHandler(unsubscribe -> { | ||||
|             log.debug("[handle][设备取消订阅,客户端 ID: {},主题: {}]", clientId, unsubscribe.topics()); | ||||
|             endpoint.unsubscribeAcknowledge(unsubscribe.messageId()); | ||||
|         }); | ||||
|  | ||||
|         // 6. 设置 QoS 2消息的 PUBREL 处理器 | ||||
|         // 7. 设置 QoS 2消息的 PUBREL 处理器 | ||||
|         endpoint.publishReleaseHandler(endpoint::publishComplete); | ||||
|  | ||||
|         // 7. 设置断开连接处理器 | ||||
|         // 8. 设置断开连接处理器 | ||||
|         endpoint.disconnectHandler(v -> { | ||||
|             log.debug("[handle][设备断开连接,客户端 ID: {}]", clientId); | ||||
|             cleanupConnection(endpoint); | ||||
|         }); | ||||
|  | ||||
|         // 8. 接受连接 | ||||
|         // 9. 接受连接 | ||||
|         endpoint.accept(false); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -103,7 +103,6 @@ yudao: | ||||
|           port: 1883 | ||||
|           max-message-size: 8192 | ||||
|           connect-timeout-seconds: 60 | ||||
|           keep-alive-timeout-seconds: 300 | ||||
|           ssl-enabled: false | ||||
|  | ||||
| --- #################### 日志相关配置 #################### | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 haohao
					haohao