SpringBoot集成mqtt的多模塊項(xiàng)目配置詳解
前言
近期為了準(zhǔn)備畢設(shè),準(zhǔn)備使用SpringBoot搭建mqtt后端,本篇主要記錄了在IDEA中搭建SpringBoot mqtt的多模塊項(xiàng)目的過程
開發(fā)工具及系統(tǒng)環(huán)境
- IDE:IntelliJ IDEA 2020.2
- 操作系統(tǒng):Windows 10 2004
- Java Version:1.8
- SpringBoot Version:2.1.17.RELEASE
項(xiàng)目路徑
Study |----study-common # 存放公共類 |----study-mapper # mapper層 |----study-mqtt # mqtt相關(guān)配置文件及接口 |----study-service # service層 |----study-serviceimpl # service的實(shí)現(xiàn)類 |----study-web # web層 |----pom.xml
配置過程
1. 搭建父項(xiàng)目
在IDEA中新建一個(gè)SpringBoot工程
這里我使用了阿里云的啟動(dòng)服務(wù),正常使用可以直接用原本的啟動(dòng)服務(wù)
根據(jù)你的需求選擇Java版本,初始化類型并配置groupID和artifactId,我這里配置成我的域名的反寫,并將artifactId定義成Study。配置完成后單擊Next
這一步選擇你需求的SpringBoot版本,我這里選擇的是2.1.17.RELEASE,然后單擊NEXT。在這一步中不需要勾選任何依賴。
選擇保存的路徑,點(diǎn)擊Finish完成創(chuàng)建。
刪除不需要的文件。將目錄下的src/
,HELP.md
,mvnw
,mvnw.cmd
等文件全部刪除(不包括.gitigore
)
至此,父項(xiàng)目一級(jí)已經(jīng)創(chuàng)建完成,最后項(xiàng)目目錄如下:
2. 搭建子項(xiàng)目
右鍵項(xiàng)目根目錄->新建->新模塊
選擇Maven,單擊Next
配置父項(xiàng),項(xiàng)目名稱以及構(gòu)建坐標(biāo),完成后單擊Finish。這里以study-common模塊為例
以此類推創(chuàng)建整個(gè)項(xiàng)目,項(xiàng)目目錄如圖所示
至此,我們搭建完所有的子項(xiàng)目,接下來開始配置各個(gè)項(xiàng)目的pom文件
3. 配置各個(gè)模塊
1. 配置父項(xiàng)目
配置父項(xiàng)目的pom.xml文件
父項(xiàng)目的pom.xml主要是對(duì)子項(xiàng)目的引用起到一個(gè)約束作用,固在父項(xiàng)目的pom.xml需要使用dependencyManagement這一項(xiàng)來約束子項(xiàng)目中各個(gè)依賴的版本。在父項(xiàng)目中可以引用子項(xiàng)目都用得到的引用。父項(xiàng)目的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這一項(xiàng)指向父項(xiàng)目即可,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>
創(chuàng)建所需要的類和接口
配置完pom.xml后,就可以在目錄下創(chuàng)建所需要的類以及接口。在本項(xiàng)目中我分別創(chuàng)建了作為pojo類的UserBean和作為json返回結(jié)果的JsonResult類作為通用類,項(xiàng)目結(jié)構(gòu)如下:
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模塊對(duì)應(yīng)的是mapper層,也就是我們常說的DAO層,用于與數(shù)據(jù)庫(kù)進(jìn)行通信,讀寫操作。這里我們用的持久層框架是Mybatis,連接的數(shù)據(jù)庫(kù)是mysql數(shù)據(jù)庫(kù)。同時(shí)需要common模塊中的各個(gè)pojo類,這里需要引入各個(gè)引用。操作步驟如下:
配置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> <!-- 內(nèi)部引用 --> <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文件夾下創(chuàng)建mapper目錄,并編寫用于映射的xml文件。同時(shí)創(chuàng)建對(duì)應(yīng)的接口,本項(xiàng)目工程目錄大致如下:
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層,主要是一些服務(wù)接口方便給controller層調(diào)用。步驟如下:
配置pom.xml文件
service層需要用到common模塊中的pojo類,這里需要對(duì)該模塊添加依賴項(xiàng)
<?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各個(gè)接口
這里接口與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接口的各個(gè)實(shí)現(xiàn)類,實(shí)現(xiàn)步驟如下:
配置pom.xml文件
serviceimpl需要mapper層的支持,需要實(shí)現(xiàn)service層的各個(gè)接口,也需要引用到common模塊中的pojo類,我們直接加上這三項(xiàng)的依賴
<?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>
根據(jù)service各個(gè)接口編寫實(shí)現(xiàn)類
UserServiceimpl.java 注意在實(shí)現(xiàn)類上要加上@Service標(biāo)注以用于SpringBoot框架識(shí)別
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層需要配置啟動(dòng)類以及配置文件,內(nèi)容較多,配置步驟如下:
配置pom.xml文件
Web層將直接引用Service層的各個(gè)接口,Common模塊的各個(gè)類,這里我們直接加上依賴
<?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>
編寫各個(gè)Controller以及配置文件
先根據(jù)以下的項(xiàng)目結(jié)構(gòu)創(chuàng)建對(duì)應(yīng)的文件,項(xiàng)目結(jié)構(gòu)如下:
study-web |----pom.xml |----src |----test |----java |----com.itbu.study.web |----WebApplicationTests.java #測(cè)試類 |----main |----java |----com.itbu.study.web |----WebApplication.java |----controller |----ApiController.java |----resources |----config |----application.yml |----application-dev.yml
編寫啟動(dòng)類,記得加上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(); } }
在配置文件中設(shè)置數(shù)據(jù)源和mapper映射文件以及監(jiān)聽端口
application-dev.xml
server: port: 10000 mybatis: mapper-locations: classpath*:mapper/*.xml #注意此處與未分模塊的區(qū)別 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. 測(cè)試
至此,我們以及配置完了一個(gè)多模塊的MQTT后端基本項(xiàng)目,接下來進(jìn)行簡(jiǎn)單測(cè)試
運(yùn)行項(xiàng)目并在瀏覽器中輸入http://localhost:10000/api/index, 返回以下結(jié)果表明測(cè)試成功
4. 配置MQTT模塊
前面我們完成了SpringBoot基礎(chǔ)項(xiàng)目的配置,接下來我們將mqtt也做成模塊,步驟如下:
配置pom.xml文件
我們集成mqtt功能主要使用了spring-integration-mqtt這個(gè)jar包,所以我們?cè)趐om中添加對(duì)這個(gè)包的依賴,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各個(gè)配置類以及方法
項(xiàng)目結(jié)構(gòu)如下:
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); }
在啟動(dòng)類中添加@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") //這里添加,不然無法自動(dòng)注入 public class WebApplication { public static void main(String[] args) { SpringApplication.run(WebApplication.class, args); } }
編寫對(duì)應(yīng)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"); } }
測(cè)試
首先我們運(yùn)行后端項(xiàng)目,可以看到日志打出以下輸出,說明后端項(xiàng)目正常啟動(dòng)
然后我們使用mqtt.fx這個(gè)軟件往訂閱主題default發(fā)送helloworld
發(fā)現(xiàn)日志打印如下信息,表面輸入通道正常:
然后我們?cè)跒g覽器中輸入http://localhost:10000/api/mqtt?msg=1234556 并按下回車,瀏覽器顯示如下:
可以看到日志中打印了如下內(nèi)容:
因?yàn)槲覀冇嗛喌闹黝}也是default,所以也收到了生產(chǎn)者發(fā)送的信息,我們打開mqtt.fx, 訂閱default主題,可以收到如下信息:
測(cè)試成功
最后放上工程的源碼:GitHub
到此這篇關(guān)于SpringBoot集成mqtt的多模塊項(xiàng)目配置詳解的文章就介紹到這了,更多相關(guān)SpringBoot mqtt多模塊內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot在一定時(shí)間內(nèi)限制接口請(qǐng)求次數(shù)的實(shí)現(xiàn)示例
在項(xiàng)目中,接口的暴露在外面,很多人就會(huì)惡意多次快速請(qǐng)求,本文主要介紹了SpringBoot在一定時(shí)間內(nèi)限制接口請(qǐng)求次數(shù)的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2022-03-03聊聊springboot2.2.3升級(jí)到2.4.0單元測(cè)試的區(qū)別
這篇文章主要介紹了springboot 2.2.3 升級(jí)到 2.4.0單元測(cè)試的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10java使用歸并刪除法刪除二叉樹中節(jié)點(diǎn)的方法
這篇文章主要介紹了java使用歸并刪除法刪除二叉樹中節(jié)點(diǎn)的方法,實(shí)例分析了java二叉樹算法的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05SpringMVC解析post請(qǐng)求參數(shù)詳解
今天小編就為大家分享一篇解決SpringMVC接收不到ajaxPOST參數(shù)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-08-08SpringBoot實(shí)現(xiàn)PDF添加水印的三種方法
本文主要介紹了SpringBoot實(shí)現(xiàn)PDF添加水印的三種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例
這篇文章主要介紹了Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07SpringBoot+Ajax+redis實(shí)現(xiàn)隱藏重要接口地址的方法
這篇文章主要介紹了SpringBoot+Ajax+redis實(shí)現(xiàn)隱藏重要接口地址,本篇文章主要講訴使用SpringBoot項(xiàng)目配合Ajax和redis實(shí)現(xiàn)隱藏重要接口地址,這里我以隱藏秒殺地址為例,需要的朋友可以參考下2024-03-03SpringBoot AOP控制Redis自動(dòng)緩存和更新的示例
今天小編就為大家分享一篇關(guān)于SpringBoot AOP控制Redis自動(dòng)緩存和更新的示例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01