SpringBoot集成mqtt的多模塊項(xiàng)目配置詳解
前言
近期為了準(zhǔn)備畢設(shè),準(zhǔn)備使用SpringBoot搭建mqtt后端,本篇主要記錄了在IDEA中搭建SpringBoot mqtt的多模塊項(xiàng)目的過(guò)程
開發(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
配置過(guò)程
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)目,接下來(lái)開始配置各個(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)來(lái)約束子項(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層,也就是我們常說(shuō)的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模塊
接下來(lái)就到了核心部分,也就是與不分模塊配置差異較大的部分。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)目,接下來(lái)進(jìn)行簡(jiǎn)單測(cè)試
運(yùn)行項(xiàng)目并在瀏覽器中輸入http://localhost:10000/api/index, 返回以下結(jié)果表明測(cè)試成功

4. 配置MQTT模塊
前面我們完成了SpringBoot基礎(chǔ)項(xiàng)目的配置,接下來(lái)我們將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") //這里添加,不然無(wú)法自動(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)目,可以看到日志打出以下輸出,說(shuō)明后端項(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-10
java使用歸并刪除法刪除二叉樹中節(jié)點(diǎn)的方法
這篇文章主要介紹了java使用歸并刪除法刪除二叉樹中節(jié)點(diǎn)的方法,實(shí)例分析了java二叉樹算法的相關(guān)操作技巧,需要的朋友可以參考下2015-05-05
SpringMVC解析post請(qǐng)求參數(shù)詳解
今天小編就為大家分享一篇解決SpringMVC接收不到ajaxPOST參數(shù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-08-08
SpringBoot實(shí)現(xiàn)PDF添加水印的三種方法
本文主要介紹了SpringBoot實(shí)現(xiàn)PDF添加水印的三種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例
這篇文章主要介紹了Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
SpringBoot+Ajax+redis實(shí)現(xiàn)隱藏重要接口地址的方法
這篇文章主要介紹了SpringBoot+Ajax+redis實(shí)現(xiàn)隱藏重要接口地址,本篇文章主要講訴使用SpringBoot項(xiàng)目配合Ajax和redis實(shí)現(xiàn)隱藏重要接口地址,這里我以隱藏秒殺地址為例,需要的朋友可以參考下2024-03-03
SpringBoot AOP控制Redis自動(dòng)緩存和更新的示例
今天小編就為大家分享一篇關(guān)于SpringBoot AOP控制Redis自動(dòng)緩存和更新的示例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01

