springboot 實(shí)現(xiàn)mqtt物聯(lián)網(wǎng)的示例代碼
Springboot整合mybatisPlus+mysql+druid+swaggerUI+ mqtt 整合mqtt整合druid整合mybatis-plus完整pom完整yml整合swaggerUi整合log4j MQTT 物聯(lián)網(wǎng)系統(tǒng)基本架構(gòu)本物聯(lián)網(wǎng)系列
mqtt)
整合mqtt
<!--mqtt依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-mqtt</artifactId> </dependency>
yml
iot:
mqtt:
clientId: ${random.value}
defaultTopic: topic
shbykjTopic: shbykj_topic
url: tcp://127.0.0.1:1883
username: admin
password: admin
completionTimeout: 3000
package com.shbykj.handle.mqtt;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.stereotype.Component;
/**
* @Author: wxm
* @Description: mqtt基礎(chǔ)配置類
*/
@Getter
@Setter
@Component
@IntegrationComponentScan
@ConfigurationProperties(prefix = "iot.mqtt")
public class BykjMqttConfig {
/*
*
* 服務(wù)地址
*/
private String url;
/**
* 客戶端id
*/
private String clientId;
/*
*
* 默認(rèn)主題
*/
private String defaultTopic;
/*
*
* 用戶名和密碼*/
private String username;
private String password;
/**
* 超時(shí)時(shí)間
*/
private int completionTimeout;
/**
* shbykj自定義主題
*/
private String shbykjTopic;
}
package com.shbykj.handle.mqtt.producer;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.handler.annotation.Header;
/**
* @description rabbitmq mqtt協(xié)議網(wǎng)關(guān)接口
* @date 2020/6/8 18:26
*/
@MessagingGateway(defaultRequestChannel = "iotMqttInputChannel")
public interface IotMqttGateway {
void sendMessage2Mqtt(String data);
void sendMessage2Mqtt(String data, @Header(MqttHeaders.TOPIC) String topic);
void sendMessage2Mqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);
}
package com.shbykj.handle.mqtt;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
@Configuration
public class IotMqttProducerConfig {
public final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private BykjMqttConfig mqttConfig;
/*
*
* MQTT連接器選項(xiàng)
* *
*/
@Bean(value = "getMqttConnectOptions")
public MqttConnectOptions getMqttConnectOptions1() {
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
// 設(shè)置是否清空session,這里如果設(shè)置為false表示服務(wù)器會(huì)保留客戶端的連接記錄,這里設(shè)置為true表示每次連接到服務(wù)器都以新的身份連接
mqttConnectOptions.setCleanSession(true);
// 設(shè)置超時(shí)時(shí)間 單位為秒
mqttConnectOptions.setConnectionTimeout(mqttConfig.getCompletionTimeout());
mqttConnectOptions.setAutomaticReconnect(true);
mqttConnectOptions.setUserName(mqttConfig.getUsername());
mqttConnectOptions.setPassword(mqttConfig.getPassword().toCharArray());
mqttConnectOptions.setServerURIs(new String[]{mqttConfig.getUrl()});
// 設(shè)置會(huì)話心跳時(shí)間 單位為秒 服務(wù)器會(huì)每隔1.5*20秒的時(shí)間向客戶端發(fā)送心跳判斷客戶端是否在線,但這個(gè)方法并沒有重連的機(jī)制
mqttConnectOptions.setKeepAliveInterval(10);
// 設(shè)置“遺囑”消息的話題,若客戶端與服務(wù)器之間的連接意外中斷,服務(wù)器將發(fā)布客戶端的“遺囑”消息。
//mqttConnectOptions.setWill("willTopic", WILL_DATA, 2, false);
return mqttConnectOptions;
}
/**
* mqtt工廠
*
* @return
*/
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
// factory.setServerURIs(mqttConfig.getServers());
factory.setConnectionOptions(getMqttConnectOptions1());
return factory;
}
@Bean
public MessageChannel iotMqttInputChannel() {
return new DirectChannel();
}
// @Bean
// @ServiceActivator(inputChannel = "iotMqttInputChannel")
// public MessageHandler mqttOutbound() {
// MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(mqttConfig.getClientId(), mqttClientFactory());
// messageHandler.setAsync(false);
// messageHandler.setDefaultQos(2);
// messageHandler.setDefaultTopic(mqttConfig.getDefaultTopic());
// return messageHandler;
// }
@Bean
@ServiceActivator(inputChannel = "iotMqttInputChannel")
public MessageHandler handlerTest() {
return message -> {
try {
String string = message.getPayload().toString();
System.out.println(string);
} catch (MessagingException ex) {
ex.printStackTrace();
logger.info(ex.getMessage());
}
};
}
}
package com.shbykj.handle.mqtt;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
/**
* @Author: xiaofu
* @Description: 消息訂閱配置
* @date 2020/6/8 18:24
*/
@Configuration
public class IotMqttSubscriberConfig {
public final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private MqttReceiveHandle mqttReceiveHandle;
@Autowired
private BykjMqttConfig mqttConfig;
/*
*
* MQTT連接器選項(xiàng)
* *
*/
@Bean(value = "getMqttConnectOptions")
public MqttConnectOptions getMqttConnectOptions1() {
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
// 設(shè)置是否清空session,這里如果設(shè)置為false表示服務(wù)器會(huì)保留客戶端的連接記錄,這里設(shè)置為true表示每次連接到服務(wù)器都以新的身份連接
mqttConnectOptions.setCleanSession(true);
// 設(shè)置超時(shí)時(shí)間 單位為秒
mqttConnectOptions.setConnectionTimeout(10);
mqttConnectOptions.setAutomaticReconnect(true);
// mqttConnectOptions.setUserName(mqttConfig.getUsername());
// mqttConnectOptions.setPassword(mqttConfig.getPassword().toCharArray());
mqttConnectOptions.setServerURIs(new String[]{mqttConfig.getUrl()});
// 設(shè)置會(huì)話心跳時(shí)間 單位為秒 服務(wù)器會(huì)每隔1.5*20秒的時(shí)間向客戶端發(fā)送心跳判斷客戶端是否在線,但這個(gè)方法并沒有重連的機(jī)制
mqttConnectOptions.setKeepAliveInterval(10);
// 設(shè)置“遺囑”消息的話題,若客戶端與服務(wù)器之間的連接意外中斷,服務(wù)器將發(fā)布客戶端的“遺囑”消息。
//mqttConnectOptions.setWill("willTopic", WILL_DATA, 2, false);
return mqttConnectOptions;
}
/*
*
*MQTT信息通道(生產(chǎn)者)
**
*/
@Bean
public MessageChannel iotMqttOutboundChannel() {
return new DirectChannel();
}
/*
*
*MQTT消息處理器(生產(chǎn)者)
**
*/
@Bean
@ServiceActivator(inputChannel = "iotMqttOutboundChannel")
public MessageHandler mqttOutbound() {
MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(mqttConfig.getClientId(), mqttClientFactory());
messageHandler.setAsync(true);
messageHandler.setDefaultTopic(mqttConfig.getDefaultTopic());
return messageHandler;
}
/*
*
*MQTT工廠
**
*/
@Bean
public MqttPahoClientFactory mqttClientFactory() {
DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
// factory.setServerURIs(mqttConfig.getServers());
factory.setConnectionOptions(getMqttConnectOptions1());
return factory;
}
/*
*
*MQTT信息通道(消費(fèi)者)
**
*/
@Bean
public MessageChannel iotMqttInputChannel() {
return new DirectChannel();
}
/**
* 配置client,監(jiān)聽的topic
* MQTT消息訂閱綁定(消費(fèi)者)
***/
@Bean
public MessageProducer inbound() {
MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(mqttConfig.getClientId(), mqttClientFactory(), mqttConfig.getDefaultTopic(), mqttConfig.getShbykjTopic());
adapter.setCompletionTimeout(mqttConfig.getCompletionTimeout());
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(2);
adapter.setOutputChannel(iotMqttInputChannel());
return adapter;
}
/**
* @author wxm
* @description 消息訂閱
* @date 2020/6/8 18:20
*/
@Bean
@ServiceActivator(inputChannel = "iotMqttInputChannel")
public MessageHandler handler() {
return new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
//處理接收消息
try {
mqttReceiveHandle.handle(message);
} catch (Exception e) {
logger.warn("消息處理異常"+e.getMessage());
e.printStackTrace();
}
}
};
}
}
package com.shbykj.handle.mqtt;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.shbykj.handle.common.DataCheck;
import com.shbykj.handle.common.RedisKey;
import com.shbykj.handle.common.RedisUtils;
import com.shbykj.handle.common.constants.Constants;
import com.shbykj.handle.common.model.ShbyCSDeviceEntity;
import com.shbykj.handle.common.model.sys.SysInstrument;
import com.shbykj.handle.resolve.mapper.SysInstrumentMapper;
import com.shbykj.handle.resolve.util.DateUtils;
import com.shbykj.handle.resolve.util.ShbyCSDeviceUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/*
*
* mqtt客戶端消息處理類
* **/
@Component
@Slf4j
@Transactional
public class MqttReceiveHandle implements MqttCallback {
private static final Logger logger = LoggerFactory.getLogger(MqttReceiveHandle.class);
@Value("${shbykj.checkCrc}")
private boolean checkcrc;
@Autowired
private SysInstrumentMapper sysInstrumentMapper;
@Autowired
private RedisUtils redisUtils;
public static BidiMap bidiMap = new DualHashBidiMap();
//記錄bykj協(xié)議內(nèi)容
public static Map<String, Map<String, Object>> devMap = new HashMap();
//記錄上限數(shù)量
// public static Map<String, ChannelHandlerContext> ctxMap = new HashMap();
public void handle(Message<?> message) {
try {
logger.info("{},客戶端號(hào):{},主題:{},QOS:{},消息接收到的數(shù)據(jù):{}", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()), message.getHeaders().get(MqttHeaders.ID), message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC), message.getHeaders().get(MqttHeaders.RECEIVED_QOS), message.getPayload());
//處理mqtt數(shù)據(jù)
this.handle(message.getPayload().toString());
} catch (Exception e) {
e.printStackTrace();
log.error("處理錯(cuò)誤" + e.getMessage());
}
}
private void handle(String str) throws Exception {
boolean flag = this.dataCheck(str);
if (flag) {
ShbyCSDeviceEntity shbyCSDeviceEntity = ShbyCSDeviceUtils.convertToSysInstrumentEntity(str);
String deviceNumber = shbyCSDeviceEntity.getPN();
String smpId = shbyCSDeviceEntity.getSMP_ID();
String smpName = shbyCSDeviceEntity.getSMP_NAME();
String smpWt = shbyCSDeviceEntity.getSMP_WT();
if (StringUtils.isEmpty(smpId) || StringUtils.isEmpty(smpName) || StringUtils.isEmpty(smpWt)) {
log.error("過濾無實(shí)際作用報(bào)文信息", str);
logger.error("過濾無實(shí)際作用報(bào)文信息", str);
return;
}
//判斷設(shè)備id是否存在數(shù)據(jù)庫中,存在才進(jìn)行數(shù)據(jù)部分處理
//不存在就提醒需要添加設(shè)備:
QueryWrapper<SysInstrument> wrapper = new QueryWrapper();
wrapper.eq("number", deviceNumber);
wrapper.eq("is_deleted", Constants.NO);
SysInstrument sysInstrument = sysInstrumentMapper.selectOne(wrapper);
if (null == sysInstrument) {
log.error("碳氧儀不存在或已刪除,設(shè)備號(hào):{}", deviceNumber);
logger.error("碳氧儀不存在或已刪除,設(shè)備號(hào):{}", deviceNumber);
return;
}
try {
//增加實(shí)時(shí)數(shù)據(jù)
String instrumentId = sysInstrument.getId().toString();
String realDataKey = RedisKey.CSdevice_DATA_KEY + instrumentId;
this.redisUtils.set(realDataKey, shbyCSDeviceEntity);
System.out.println(shbyCSDeviceEntity);
//通訊時(shí)間
String onlineTime = "shbykj_mqtt:onlines:" + instrumentId;
this.redisUtils.set(onlineTime, shbyCSDeviceEntity.getDataTime(), (long) Constants.RedisTimeOut.REAL_TIME_OUT);
log.info("實(shí)時(shí)數(shù)據(jù)已經(jīng)更新:設(shè)備主鍵id" + instrumentId);
logger.info("{} 實(shí)時(shí)數(shù)據(jù)已經(jīng)更新:設(shè)備主鍵id:{}",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),instrumentId);
} catch (Exception var1) {
log.error("redis處理實(shí)時(shí)報(bào)文數(shù)據(jù)邏輯異常 :" + var1.getMessage());
logger.error("redis處理實(shí)時(shí)報(bào)文數(shù)據(jù)邏輯異常 :" + var1.getMessage());
}
}
}
private boolean dataCheck(String message) {
boolean flag = DataCheck.receiverCheck(message);
if (!flag) {
return false;
} else {
int i = message.indexOf("QN=");
if (i < 0) {
log.warn("數(shù)據(jù)包中沒有QN號(hào)碼: " + message);
logger.warn("數(shù)據(jù)包中沒有QN號(hào)碼: " + message);
return false;
} else {
i = message.indexOf("PN=");
if (i < 0) {
log.warn("數(shù)據(jù)包中沒有PN號(hào)碼: " + message);
logger.warn("數(shù)據(jù)包中沒有PN號(hào)碼: " + message);
return false;
} else {
if (this.checkcrc) {
flag = DataCheck.checkCrc(message);
if (!flag) {
log.warn("crc校驗(yàn)失敗: " + message);
logger.warn("數(shù)據(jù)包中沒有PN號(hào)碼: " + message);
return false;
}
}
return true;
}
}
}
}
/**
* 連接丟失
*
* @param throwable
*/
@Override
public void connectionLost(Throwable throwable) {
logger.warn("連接丟失-客戶端:{},原因:{}", throwable.getMessage());
}
/**
* 消息已到達(dá)
*
* @param s
* @param mqttMessage
* @throws Exception
*/
@Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
}
/**
* 完成消息回調(diào)
*
* @param iMqttDeliveryToken
*/
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
}
整合druid
pom
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
druid-bean.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置_Druid和Spring關(guān)聯(lián)監(jiān)控配置 --> <bean id="druid-stat-interceptor" class="com.alibaba.druid.support.spring.stat.DruidStatInterceptor"></bean> <!-- 方法名正則匹配攔截配置 --> <bean id="druid-stat-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut" scope="prototype"> <property name="patterns"> <list> <value>com.shbykj.*.service.*.impl.*</value> </list> </property> </bean> <aop:config proxy-target-class="true"> <aop:advisor advice-ref="druid-stat-interceptor" pointcut-ref="druid-stat-pointcut" /> </aop:config> </beans>
yml
#spring spring: main: allow-bean-definition-overriding: true # mysql DATABASE CONFIG datasource: druid: filters: stat,wall,log4j2 continueOnError: true type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/mqttdb?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # see https://github.com/alibaba/druid initialSize: 15 minIdle: 10 maxActive: 200 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true keepAlive: true maxPoolPreparedStatementPerConnectionSize: 50 connectionProperties: druid.stat.mergeSql: true druid.stat.slowSqlMillis: 5000
啟動(dòng)類加上注解@ImportResource( locations = {"classpath:druid-bean.xml"} )

整合mybatis-plus
pom
<!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>spring-wind</artifactId> <version>1.1.5</version> <exclusions> <exclusion> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.baomidou</groupId> <version>3.1.2</version> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> </dependency> <!--PageHelper分頁插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.12</version> </dependency>
yml
#mybatis mybatis-plus: mapper-locations: classpath:/mapper/*.xml typeAliasesPackage: org.spring.springboot.entity global-config: #主鍵類型 0:"數(shù)據(jù)庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數(shù)字類型唯一ID)", 3:"全局唯一ID UUID"; id-type: 3 #字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷" field-strategy: 2 #駝峰下劃線轉(zhuǎn)換 db-column-underline: true #刷新mapper 調(diào)試神器 refresh-mapper: true configuration: map-underscore-to-camel-case: true cache-enabled: false
啟動(dòng)類注解@MapperScan({"com.shbykj.handle.resolve.mapper"})
完整pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.shbykj</groupId> <artifactId>handle</artifactId> <version>0.0.1-SNAPSHOT</version> <name>handle</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <!--注意: <scope>compile</scope> 這里是正式環(huán)境,解決啟動(dòng)報(bào)錯(cuò)--> <!--idea springboot啟動(dòng)報(bào)SLF4J:Failed to load class “org.slf4j.impl.StaticLoggerBinder--> <!--參考:https://blog.csdn.net/u010696630/article/details/84991116--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> <scope>compile</scope> </dependency> <!-- Log4j2 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!--開啟日志注解--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- 排除 Spring-boot-starter 默認(rèn)的日志配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!--swagger api接口生成--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <!-- 代碼生成器的依賴 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> <exclusions> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> </exclusions> </dependency> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>spring-wind</artifactId> <version>1.1.5</version> <exclusions> <exclusion> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.baomidou</groupId> <version>3.1.2</version> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.44</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--PageHelper分頁插件--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.12</version> </dependency> <!--devtools熱部署--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>runtime</scope> </dependency> <!--json轉(zhuǎn)換工具--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!--工具類--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.8.1</version> </dependency> <!--google--> <!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>30.0-jre</version> </dependency> <!-- 工具類庫 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-core</artifactId> <version>5.5.0</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
完整yml
server: port: 8082 #spring spring: devtools: restart: enabled: true main: allow-bean-definition-overriding: true # mysql DATABASE CONFIG datasource: druid: filters: stat,wall,log4j2 continueOnError: true type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://localhost:3306/mqttdb?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # see https://github.com/alibaba/druid initialSize: 15 minIdle: 10 maxActive: 200 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true keepAlive: true maxPoolPreparedStatementPerConnectionSize: 50 connectionProperties: druid.stat.mergeSql: true druid.stat.slowSqlMillis: 5000 shbykj: checkCrc: false #mybatis mybatis-plus: mapper-locations: classpath:/mapper/*.xml typeAliasesPackage: org.spring.springboot.entity global-config: #主鍵類型 0:"數(shù)據(jù)庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數(shù)字類型唯一ID)", 3:"全局唯一ID UUID"; id-type: 3 #字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷" field-strategy: 2 #駝峰下劃線轉(zhuǎn)換 db-column-underline: true #刷新mapper 調(diào)試神器 refresh-mapper: true configuration: map-underscore-to-camel-case: true cache-enabled: false #logging logging: config: classpath:log4j2-demo.xml
整合swaggerUi
pom
<!--swagger api接口生成--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <!--解決報(bào)錯(cuò):swagger:Illegal DefaultValue null for parameter type integer. java.lang.NumberFormatException: For input string: "".--> <!--1.5.21的AbstractSerializableParameter.getExample()方法增加了對(duì)空字符串的判斷--> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.21</version> </dependency> <!-- 代碼生成器的依賴 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> <exclusions> <exclusion> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </exclusion> </exclusions> </dependency>
使用
package com.shbykj.handle.web.wx;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.shbykj.handle.common.RetMsgData;
import com.shbykj.handle.common.State;
import com.shbykj.handle.common.model.sys.SysInstrument;
import com.shbykj.handle.h.service.ISysInstrumentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 監(jiān)測點(diǎn)接口
*
* @author
* @date 2021-01-15 16:49
*/
@RestController
@RequestMapping({"/api/wxapoint"})
@Api(
tags = {"小程序 監(jiān)測點(diǎn)接口"}
)
public class CSDevicesController extends BaseController {
@Autowired
private ISysInstrumentService sysInstrumentService;
public CSDevicesController() {
}
@ApiOperation(
value = "分頁查詢",
notes = "分頁查詢站點(diǎn)信息"
)
@ApiImplicitParams({@ApiImplicitParam(
name = "number",
value = "設(shè)備編號(hào)",
paramType = "query",
dataType = "String"
), @ApiImplicitParam(
name = "page",
value = "頁碼 從1開始",
required = false,
dataType = "long",
paramType = "query"
), @ApiImplicitParam(
name = "size",
value = "頁數(shù)",
required = false,
dataType = "long",
paramType = "query"
)})
@GetMapping({"/pageByNumber"})
public RetMsgData<IPage<SysInstrument>> pageByNumber(@RequestParam(required = false) String number) {
RetMsgData msg = new RetMsgData();
try {
IPage<SysInstrument> page1 = this.getPage();
page1 = sysInstrumentService.pageByNumber(number, page1);
msg.setData(page1);
} catch (Exception var5) {
msg.setState(State.RET_STATE_SYSTEM_ERROR);
this.logger.error(var5.getMessage());
}
return msg;
}
}
package com.shbykj.handle.common.model.sys;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Date;
@TableName("instrument")
@ApiModel("儀器配置表字段信息")
public class SysInstrument implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(
value = "id",
type = IdType.AUTO
)
@ApiModelProperty(
value = "id",
name = "id",
required = true
)
private Long id;
@TableField("name")
@ApiModelProperty(
value = "名稱 儀器名稱",
name = "name"
)
private String name;
@TableField("number")
@ApiModelProperty(
value = "編號(hào) 儀器編號(hào)(PN)",
name = "number"
)
private String number;
@TableField("manufacturer")
@ApiModelProperty(
value = "生產(chǎn)廠商 生產(chǎn)廠商",
name = "manufacturer"
)
private String manufacturer;
@TableField("gmt_create")
@ApiModelProperty(
value = "創(chuàng)建時(shí)間",
name = "gmt_create"
)
private Date gmtCreate;
@TableField("gmt_modified")
@ApiModelProperty(
value = "更新時(shí)間",
name = "gmt_modified"
)
private Date gmtModified;
@TableField("is_deleted")
@ApiModelProperty(
value = "表示刪除,0 表示未刪除 默認(rèn)0",
name = "is_deleted"
)
private Integer isDeleted;
@TableField("device_type")
@ApiModelProperty(
value = "設(shè)備類型(PT)",
name = "device_type"
)
private String deviceType;
public SysInstrument() {
}
public Long getId() {
return this.id;
}
public String getName() {
return this.name;
}
public String getNumber() {
return this.number;
}
public String getManufacturer() {
return this.manufacturer;
}
public Date getGmtCreate() {
return this.gmtCreate;
}
public Date getGmtModified() {
return this.gmtModified;
}
public Integer getIsDeleted() {
return this.isDeleted;
}
public String getDeviceType() {
return this.deviceType;
}
public void setId(final Long id) {
this.id = id;
}
public void setName(final String name) {
this.name = name;
}
public void setNumber(final String number) {
this.number = number;
}
public void setManufacturer(final String manufacturer) {
this.manufacturer = manufacturer;
}
public void setGmtCreate(final Date gmtCreate) {
this.gmtCreate = gmtCreate;
}
public void setGmtModified(final Date gmtModified) {
this.gmtModified = gmtModified;
}
public void setIsDeleted(final Integer isDeleted) {
this.isDeleted = isDeleted;
}
public void setDeviceType(final String deviceType) {
this.deviceType = deviceType;
}
public String toString() {
return "SysInstrument(id=" + this.getId() + ", name=" + this.getName() + ", number=" + this.getNumber() + ", manufacturer=" + this.getManufacturer() + ", gmtCreate=" + this.getGmtCreate() + ", gmtModified=" + this.getGmtModified() + ", isDeleted=" + this.getIsDeleted() + ", deviceType=" + this.getDeviceType() + ")";
}
}
整合log4j
http://www.dbjr.com.cn/article/152599.htm
MQTT 物聯(lián)網(wǎng)系統(tǒng)基本架構(gòu)
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shbykj</groupId>
<artifactId>handle_mqtt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>handle_mqtt</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
</properties>
<dependencies>
<!--mqtt依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-mqtt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--注意: <scope>compile</scope> 這里是正式環(huán)境,解決啟動(dòng)報(bào)錯(cuò)-->
<!--idea springboot啟動(dòng)報(bào)SLF4J:Failed to load class “org.slf4j.impl.StaticLoggerBinder-->
<!--參考:https://blog.csdn.net/u010696630/article/details/84991116-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
<scope>compile</scope>
</dependency>
<!-- Log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- 排除 Spring-boot-starter 默認(rèn)的日志配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--swagger api接口生成-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--解決報(bào)錯(cuò):swagger:Illegal DefaultValue null for parameter type integer. java.lang.NumberFormatException: For input string: "".-->
<!--1.5.21的AbstractSerializableParameter.getExample()方法增加了對(duì)空字符串的判斷-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.21</version>
</dependency>
<!-- 代碼生成器的依賴 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--其他工具-->
<!--devtools熱部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>runtime</scope>
</dependency>
<!--json轉(zhuǎn)換工具-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--工具類-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version>
</dependency>
<!--google-->
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.0-jre</version>
</dependency>
<!-- 工具類庫 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.5.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--工具類-->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>spring-wind</artifactId>
<version>1.1.5</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<version>3.1.2</version>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.44</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--PageHelper分頁插件-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
yml
server:
port: 8082
iot:
mqtt:
clientId: ${random.value}
defaultTopic: topic
shbykjTopic: shbykj_topic
url: tcp://127.0.0.1:1883
username: admin
password: admin
completionTimeout: 3000
#微信小程序相關(guān)參數(shù)
shbykjWeixinAppid: wxae343ca8948f97c4
shbykjSecret: 9e168c92702efc06cb12fa22680f049a
#spring
spring:
devtools:
restart:
enabled: true
main:
allow-bean-definition-overriding: true
# mysql DATABASE CONFIG
datasource:
druid:
filters: stat,wall,log4j2
continueOnError: true
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/mqttdb?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
# see https://github.com/alibaba/druid
initialSize: 15
minIdle: 10
maxActive: 200
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
validationQuery: SELECT 1
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
keepAlive: true
maxPoolPreparedStatementPerConnectionSize: 50
connectionProperties:
druid.stat.mergeSql: true
druid.stat.slowSqlMillis: 5000
shbykj:
checkCrc: false
#mybatis
mybatis-plus:
mapper-locations: classpath:/mapper/*.xml
typeAliasesPackage: org.spring.springboot.entity
global-config:
#主鍵類型 0:"數(shù)據(jù)庫ID自增", 1:"用戶輸入ID",2:"全局唯一ID (數(shù)字類型唯一ID)", 3:"全局唯一ID UUID";
id-type: 3
#字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
field-strategy: 2
#駝峰下劃線轉(zhuǎn)換
db-column-underline: true
#刷新mapper 調(diào)試神器
refresh-mapper: true
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
#log4j打印sql日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#logging
logging:
config: classpath:log4j2-demo.xml
到此這篇關(guān)于springboot 實(shí)現(xiàn)mqtt物聯(lián)網(wǎng)的文章就介紹到這了,更多相關(guān)springboot 實(shí)現(xiàn)mqtt物聯(lián)網(wǎng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合MQTT并實(shí)現(xiàn)異步線程調(diào)用的問題
- SpringBoot集成mqtt的多模塊項(xiàng)目配置詳解
- SpringBoot+MQTT+apollo實(shí)現(xiàn)訂閱發(fā)布功能的示例
- springboot集成mqtt的實(shí)踐開發(fā)
- SpringBoot+netty-socketio實(shí)現(xiàn)服務(wù)器端消息推送
- SpringBoot+WebSocket+Netty實(shí)現(xiàn)消息推送的示例代碼
- SpringBoot實(shí)現(xiàn)釘釘機(jī)器人消息推送的示例代碼
- springboot整合mqtt實(shí)現(xiàn)消息訂閱和推送功能
相關(guān)文章
Spring Boot利用Thymeleaf發(fā)送Email的方法教程
spring Boot默認(rèn)就是使用thymeleaf模板引擎的,下面這篇文章主要給大家介紹了關(guān)于在Spring Boot中利用Thymeleaf發(fā)送Email的方法教程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-08-08
Java 字符串轉(zhuǎn)float運(yùn)算 float轉(zhuǎn)字符串的方法
今天小編就為大家分享一篇Java 字符串轉(zhuǎn)float運(yùn)算 float轉(zhuǎn)字符串的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
SpringCloud與Consul集成實(shí)現(xiàn)負(fù)載均衡功能
負(fù)載均衡基本概念有:實(shí)服務(wù)、實(shí)服務(wù)組、虛服務(wù)、調(diào)度算法、持續(xù)性等,其常用應(yīng)用場景主要是服務(wù)器負(fù)載均衡,鏈路負(fù)載均衡。這篇文章主要介紹了SpringCloud與Consul集成實(shí)現(xiàn)負(fù)載均衡 ,需要的朋友可以參考下2018-09-09
java 操作gis geometry類型數(shù)據(jù)方式
這篇文章主要介紹了java 操作gis geometry類型數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
java 中sendredirect()和forward()方法的區(qū)別
這篇文章主要介紹了java 中sendredirect()和forward()方法的區(qū)別,需要的朋友可以參考下2017-08-08
Spring?Data?Jpa返回自定義對(duì)象的3種方法實(shí)例
在使用Spring Data Jpa框架時(shí),根據(jù)業(yè)務(wù)需求我們通常需要進(jìn)行復(fù)雜的數(shù)據(jù)庫查詢,下面這篇文章主要給大家介紹了關(guān)于Spring?Data?Jpa返回自定義對(duì)象的3種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
Java實(shí)現(xiàn)在線聊天室(層層遞進(jìn))
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)在線聊天室,層層遞進(jìn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09

