SpringBoot集成mqtt的多模塊項目配置詳解
前言
近期為瞭準備畢設,準備使用SpringBoot搭建mqtt後端,本篇主要記錄瞭在IDEA中搭建SpringBoot mqtt的多模塊項目的過程
開發工具及系統環境
- IDE:IntelliJ IDEA 2020.2
- 操作系統:Windows 10 2004
- Java Version:1.8
- SpringBoot Version:2.1.17.RELEASE
項目路徑
Study |----study-common # 存放公共類 |----study-mapper # mapper層 |----study-mqtt # mqtt相關配置文件及接口 |----study-service # service層 |----study-serviceimpl # service的實現類 |----study-web # web層 |----pom.xml
配置過程
1. 搭建父項目
在IDEA中新建一個SpringBoot工程
這裡我使用瞭阿裡雲的啟動服務,正常使用可以直接用原本的啟動服務
根據你的需求選擇Java版本,初始化類型並配置groupID和artifactId,我這裡配置成我的域名的反寫,並將artifactId定義成Study。配置完成後單擊Next
這一步選擇你需求的SpringBoot版本,我這裡選擇的是2.1.17.RELEASE,然後單擊NEXT。在這一步中不需要勾選任何依賴。
選擇保存的路徑,點擊Finish完成創建。
刪除不需要的文件。將目錄下的src/
,HELP.md
,mvnw
,mvnw.cmd
等文件全部刪除(不包括.gitigore
)
至此,父項目一級已經創建完成,最後項目目錄如下:
2. 搭建子項目
右鍵項目根目錄->新建->新模塊
選擇Maven,單擊Next
配置父項,項目名稱以及構建坐標,完成後單擊Finish。這裡以study-common模塊為例
以此類推創建整個項目,項目目錄如圖所示
至此,我們搭建完所有的子項目,接下來開始配置各個項目的pom文件
3. 配置各個模塊
1. 配置父項目
配置父項目的pom.xml文件
父項目的pom.xml主要是對子項目的引用起到一個約束作用,固在父項目的pom.xml需要使用dependencyManagement這一項來約束子項目中各個依賴的版本。在父項目中可以引用子項目都用得到的引用。父項目的pom.xml文件如下:
<?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> <groupId>com.itbu</groupId> <artifactId>study</artifactId> <packaging>pom</packaging> <version>1.0.0</version> <modules> <module>study-common</module> <module>study-service</module> <module>study-serviceimpl</module> <module>study-web</module> <module>study-mapper</module> <module>study-mqtt</module> </modules> <name>study</name> <description>Demo project for Spring Boot</description> <parent> <artifactId>spring-boot-starter-parent</artifactId> <groupId>org.springframework.boot</groupId> <version>2.1.17.RELEASE</version> <relativePath/> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.1.17.RELEASE</spring-boot.version> <mybatis.boot.starter.version>2.1.4</mybatis.boot.starter.version> <mysql.connector.java.version>8.0.22</mysql.connector.java.version> <druid.version>1.2.0</druid.version> <integration.version>2.3.7.RELEASE</integration.version> <stream.integration.version>5.4.2</stream.integration.version> <mqtt.integration.version>5.4.2</mqtt.integration.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis.boot.starter.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.connector.java.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>2.1.17.RELEASE</version> </plugin> </plugins> </build> </project>
2. 配置common模塊
配置pom.xml文件
common模塊主要包括一些通用的類和接口,固這裡隻需要配置下parent這一項指向父項目即可,common模塊的pom.xml配置文件如下:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>study</artifactId> <groupId>com.itbu</groupId> <version>1.0.0</version> </parent> <groupId>com.itbu.study</groupId> <artifactId>common</artifactId> <version>1.0.0</version> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <properties> <java.version>1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
創建所需要的類和接口
配置完pom.xml後,就可以在目錄下創建所需要的類以及接口。在本項目中我分別創建瞭作為pojo類的UserBean和作為json返回結果的JsonResult類作為通用類,項目結構如下:
study-common |----pom.xml |----src |----test |----main |----resources |----java |----com.itbu.study.common |----bean |----UserBean.java |----result |----JsonResult.java
UserBean.java文件
package com.itbu.study.common.bean; public class UserBean { private int id; private String username; private String password; public int getId() { return id; } public String getPassword() { return password; } public String getUsername() { return username; } public void setPassword(String password) { this.password = password; } public void setId(int id) { this.id = id; } public void setUsername(String username) { this.username = username; } public UserBean(){ } public UserBean(String username, String password){ this.username = username; this.password = password; } }
JsonResult.java文件
package com.itbu.study.common.result; public class JsonResult<T> { private int code; private String msg; private T data; public JsonResult(int Code,String msg){ this.code = Code; this.msg = msg; } public JsonResult(T data) { this.data = data; this.code = 0; this.msg = "操作成功!"; } public JsonResult(T data, String msg) { this.data = data; this.code = 0; this.msg = msg; } public String getMsg() { return msg; } public int getCode() { return code; } public T getData() { return data; } public void setData(T data) { this.data = data; } public void setMsg(String msg) { this.msg = msg; } public void setCode(int code) { this.code = code; } }
3. 配置mapper模塊
mapper模塊對應的是mapper層,也就是我們常說的DAO層,用於與數據庫進行通信,讀寫操作。這裡我們用的持久層框架是Mybatis,連接的數據庫是mysql數據庫。同時需要common模塊中的各個pojo類,這裡需要引入各個引用。操作步驟如下:
配置pom.xml文件
這裡我們需要引入mybatis,druid和mysql支持,固配置文件編寫如下:
<?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> <groupId>com.itbu.study</groupId> <artifactId>mapper</artifactId> <version>1.0.0</version> <name>mapper</name> <description>Demo project for Spring Boot</description> <packaging>jar</packaging> <parent> <artifactId>study</artifactId> <groupId>com.itbu</groupId> <version>1.0.0</version> <relativePath>../pom.xml</relativePath> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.1.17.RELEASE</spring-boot.version> </properties> <dependencies> <!-- 內部引用 --> <dependency> <groupId>com.itbu.study</groupId> <artifactId>common</artifactId> <version>1.0.0</version> </dependency> <!-- 外部引用 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
編寫接口和映射文件
和不分模塊的操作一樣,在resource文件夾下創建mapper目錄,並編寫用於映射的xml文件。同時創建對應的接口,本項目工程目錄大致如下:
study-mapper |----pom.xml |----src |----test |----main |----java |----com.itbu.study.mapper |----UserMapper.java |----resources |----mapper |----UserMapper.xml
UserMapper.java文件
package com.itbu.study.mapper; import com.itbu.study.common.bean.UserBean; import java.util.List; public interface UserMapper { List<UserBean> getAll(); }
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.itbu.study.mapper.UserMapper"> <select id="getAll" resultType="com.itbu.study.common.bean.UserBean"> select * from mqtt.user_table </select> </mapper>
4. 配置service模塊
service模塊也就是service層,主要是一些服務接口方便給controller層調用。步驟如下:
配置pom.xml文件
service層需要用到common模塊中的pojo類,這裡需要對該模塊添加依賴項
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>study</artifactId> <groupId>com.itbu</groupId> <version>1.0.0</version> <relativePath>../pom.xml</relativePath> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.itbu.study</groupId> <artifactId>service</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>service</name> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.itbu.study</groupId> <artifactId>common</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
編寫service各個接口
這裡接口與mapper層類似,就不一一贅述,這裡直接放代碼
UserService.java
package com.itbu.study.service; import com.itbu.study.common.bean.UserBean; import java.util.List; public interface UserService { List<UserBean> getAll(); }
5. 配置serviceimpl模塊
serviceimpl即service接口的各個實現類,實現步驟如下:
配置pom.xml文件
serviceimpl需要mapper層的支持,需要實現service層的各個接口,也需要引用到common模塊中的pojo類,我們直接加上這三項的依賴
<?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> <groupId>com.itbu.study</groupId> <artifactId>serviceimpl</artifactId> <version>1.0.0</version> <name>serviceimpl</name> <description>Demo project for Spring Boot</description> <packaging>jar</packaging> <parent> <artifactId>study</artifactId> <groupId>com.itbu</groupId> <version>1.0.0</version> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.1.17.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>com.itbu.study</groupId> <artifactId>common</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.itbu.study</groupId> <artifactId>service</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.itbu.study</groupId> <artifactId>mapper</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
根據service各個接口編寫實現類
UserServiceimpl.java 註意在實現類上要加上@Service標註以用於SpringBoot框架識別
package com.itbu.study.serviceimpl; import com.itbu.study.common.bean.UserBean; import com.itbu.study.mapper.UserMapper; import com.itbu.study.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<UserBean> getAll() { return userMapper.getAll(); } }
6. 配置web模塊
接下來就到瞭核心部分,也就是與不分模塊配置差異較大的部分。Web層需要配置啟動類以及配置文件,內容較多,配置步驟如下:
配置pom.xml文件
Web層將直接引用Service層的各個接口,Common模塊的各個類,這裡我們直接加上依賴
<?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> <groupId>com.itbu.study</groupId> <artifactId>serviceimpl</artifactId> <version>1.0.0</version> <name>serviceimpl</name> <description>Demo project for Spring Boot</description> <packaging>jar</packaging> <parent> <artifactId>study</artifactId> <groupId>com.itbu</groupId> <version>1.0.0</version> </parent> <properties> <java.version>1.8</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.1.17.RELEASE</spring-boot.version> </properties> <dependencies> <dependency> <groupId>com.itbu.study</groupId> <artifactId>common</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.itbu.study</groupId> <artifactId>service</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>com.itbu.study</groupId> <artifactId>mapper</artifactId> <version>1.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
編寫各個Controller以及配置文件
先根據以下的項目結構創建對應的文件,項目結構如下:
study-web |----pom.xml |----src |----test |----java |----com.itbu.study.web |----WebApplicationTests.java #測試類 |----main |----java |----com.itbu.study.web |----WebApplication.java |----controller |----ApiController.java |----resources |----config |----application.yml |----application-dev.yml
編寫啟動類,記得加上MapperScan
WebApplication.java
package com.itbu.study.web; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = {"com.itbu.study.*"}) @MapperScan("com.itbu.study.mapper") public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } }
編寫Controller層
ApiController.java
package com.itbu.study.web.controller; import com.itbu.study.common.bean.UserBean; import com.itbu.study.common.result.JsonResult; import com.itbu.study.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.xml.ws.RequestWrapper; import java.util.List; @RestController @RequestMapping("/api") public class ApiController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); public ApiController(UserService userService){ this.userService = userService; } private final UserService userService; @RequestMapping("/index") public List<UserBean> index(){ return userService.getAll(); } }
在配置文件中設置數據源和mapper映射文件以及監聽端口
application-dev.xml
server: port: 10000 mybatis: mapper-locations: classpath*:mapper/*.xml #註意此處與未分模塊的區別 spring: datasource: username: root password: 123456 url: jdbc:mysql://192.168.28.88:10090/mqtt?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC driver-class-name: com.mysql.cj.jdbc.Driver
7. 測試
至此,我們以及配置完瞭一個多模塊的MQTT後端基本項目,接下來進行簡單測試
運行項目並在瀏覽器中輸入http://localhost:10000/api/index, 返回以下結果表明測試成功
4. 配置MQTT模塊
前面我們完成瞭SpringBoot基礎項目的配置,接下來我們將mqtt也做成模塊,步驟如下:
配置pom.xml文件
我們集成mqtt功能主要使用瞭spring-integration-mqtt這個jar包,所以我們在pom中添加對這個包的依賴,pom.xml文件如下:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>study</artifactId> <groupId>com.itbu</groupId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.itbu.study</groupId> <artifactId>mqtt</artifactId> <packaging>jar</packaging> <properties> <java.version>1.8</java.version> </properties> <dependencies> <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> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
在study-web的配置文件中添加如下配置:
mqtt: enabled: true username: root password: 123456 url: tcp://192.168.28.88:15005 producer: clientId: server defaultTopic: default consumer: clientId: client defaultTopic: default
編寫MQTT各個配置類以及方法
項目結構如下:
study-mqtt |----pom.xml |----src |----test |----main |----resources |----java |----com.itbu.study.mqtt |----MqttBaseConfig.java |----MqttInConfig.java |----MqttOutConfig.java |----MqttMessageReceiver.java |----MqttMessageSender.java
MqttBaseConfig.java
package com.itbu.study.mqtt; import org.eclipse.paho.client.mqttv3.MqttConnectOptions; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory; import org.springframework.integration.mqtt.core.MqttPahoClientFactory; @Configuration @ConditionalOnProperty(value = "mqtt.enabled", havingValue = "true") public class MqttBaseConfig { @Value("${mqtt.url:#{null}}") private String[] url; @Value("${mqtt.username:}") private String username; @Value("${mqtt.password:}") private String password; @Bean public MqttPahoClientFactory factory(){ DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory(); MqttConnectOptions options = new MqttConnectOptions(); if(username != null) options.setUserName(username); if(password != null) options.setPassword(password.toCharArray()); options.setServerURIs(url); factory.setConnectionOptions(options); return factory; } }
MqttInConfig.java
package com.itbu.study.mqtt; import com.itbu.study.mqtt.MqttMessageReceiver; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 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.MqttPahoClientFactory; import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter; import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; @Configuration @ConditionalOnProperty(value = "mqtt.enabled", havingValue = "true") public class MqttInConfig { private final MqttMessageReceiver mqttMessageReceiver; public MqttInConfig(MqttMessageReceiver mqttMessageReceiver){ this.mqttMessageReceiver = mqttMessageReceiver; } @Value("${mqtt.producer.clientId:") private String clientId; @Value("${mqtt.producer.defaultTopic}") private String topic; @Bean public MessageChannel mqttInputChannel(){ return new DirectChannel(); } @Bean public MessageProducer channelInbound(MessageChannel mqttInputChannel, MqttPahoClientFactory factory){ MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(clientId, factory, topic); adapter.setCompletionTimeout(5000); adapter.setConverter(new DefaultPahoMessageConverter()); adapter.setQos(2); adapter.setOutputChannel(mqttInputChannel); return adapter; } @Bean @ServiceActivator(inputChannel = "mqttInputChannel") public MessageHandler mqttMessageHandler(){ return this.mqttMessageReceiver; } }
MqttOutConfig.java
package com.itbu.study.mqtt; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 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.MqttPahoClientFactory; import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; @Configuration @ConditionalOnProperty(value = "mqtt.enabled", havingValue = "true") public class MqttOutConfig { @Value("${mqtt.consumer.clientId:}") private String clientId; @Value("${mqtt.consumer.defaultTopic}") private String topic; @Bean public MessageChannel mqttOutputChannel(){ return new DirectChannel(); } @Bean @ServiceActivator(inputChannel = "mqttOutputChannel") public MessageHandler mqttOutBound(MqttPahoClientFactory factory){ MqttPahoMessageHandler messageHandler = new MqttPahoMessageHandler(clientId, factory); messageHandler.setAsync(true); messageHandler.setDefaultQos(2); messageHandler.setDefaultTopic(topic); return messageHandler; } }
MqttMessageReceiver.java
package com.itbu.study.mqtt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.ComponentScan; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHandler; import org.springframework.messaging.MessagingException; import org.springframework.stereotype.Component; @Component @ConditionalOnProperty(value = "mqtt.enabled",havingValue = "true") public class MqttMessageReceiver implements MessageHandler { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public void handleMessage(Message<?> message) throws MessagingException { String topic = String.valueOf(message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC)); String payload = String.valueOf(message.getPayload()); logger.info("接收到 mqtt消息, 主題:{} 消息:{}", topic, payload); } }
MqttMessageSender.java
package com.itbu.study.mqtt; import org.springframework.integration.annotation.MessagingGateway; import org.springframework.integration.mqtt.support.MqttHeaders; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; @MessagingGateway(defaultRequestChannel = "mqttOutputChannel") @Component public interface MqttMessageSender { void sendToMqtt(String data); void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload); void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload); }
在啟動類中添加@IntegrationComponentScan註解
package com.itbu.study.web; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.integration.annotation.IntegrationComponentScan; @SpringBootApplication(scanBasePackages = {"com.itbu.study.*","com.itbu.study.mqtt"}) @MapperScan("com.itbu.study.mapper") @IntegrationComponentScan(basePackages = "com.itbu.study.mqtt") //這裡添加,不然無法自動註入 public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } }
編寫對應Controller,我這裡直接在ApiController上修改瞭
package com.itbu.study.web.controller; import com.itbu.study.common.bean.UserBean; import com.itbu.study.common.result.JsonResult; import com.itbu.study.mqtt.MqttMessageSender; import com.itbu.study.service.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.xml.ws.RequestWrapper; import java.util.List; @RestController @RequestMapping("/api") public class ApiController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final MqttMessageSender mqttMessageSender; public ApiController(MqttMessageSender mqttMessageSender, UserService userService){ this.mqttMessageSender = mqttMessageSender; this.userService = userService; } private final UserService userService; @RequestMapping("/index") public List<UserBean> index(){ return userService.getAll(); } @RequestMapping("/mqtt") public JsonResult<?> mqtt_sender(@RequestParam("msg")String msg){ logger.info("Send mqtt msg: {}", msg); mqttMessageSender.sendToMqtt(msg); logger.info("Send successfully!"); return new JsonResult<>(0,"Send Successfully"); } }
測試
首先我們運行後端項目,可以看到日志打出以下輸出,說明後端項目正常啟動
然後我們使用mqtt.fx這個軟件往訂閱主題default發送helloworld
發現日志打印如下信息,表面輸入通道正常:
然後我們在瀏覽器中輸入http://localhost:10000/api/mqtt?msg=1234556 並按下回車,瀏覽器顯示如下:
可以看到日志中打印瞭如下內容:
因為我們訂閱的主題也是default,所以也收到瞭生產者發送的信息,我們打開mqtt.fx, 訂閱default主題,可以收到如下信息:
測試成功
最後放上工程的源碼:GitHub
到此這篇關於SpringBoot集成mqtt的多模塊項目配置詳解的文章就介紹到這瞭,更多相關SpringBoot mqtt多模塊內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- None Found