MQTT 在Spring Boot 中的使用

在 Spring Boot 中使用 MQTT 通常會借助 Spring Integration 項目提供的 MQTT 支持。這使得 MQTT 的集成可以很好地融入 Spring 的消息驅動和企業集成模式。

以下是如何在 Spring Boot 中集成和使用 MQTT 的詳細步驟:

前提條件:

  1. MQTT Broker:需要一個正在運行的 MQTT Broker,例如 Mosquitto, EMQX, HiveMQ, RabbitMQ (with MQTT plugin), Apollo 等。確保 Broker 的地址和端口(默認通常是 tcp://localhost:1883)。
  2. Spring Boot 項目:一個基本的 Spring Boot 項目。

步驟 1:添加依賴

在你的 pom.xml (Maven) 或 build.gradle (Gradle) 文件中添加必要的依賴:

Maven (pom.xml):

<dependencies><!-- Spring Boot Starter for core functionality --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Spring Boot Starter for Web (可選, 如果想通過 REST API 觸發 MQTT 發布) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Integration Core --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId></dependency><!-- Spring Integration MQTT Support --><dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-mqtt</artifactId><!-- Version managed by Spring Boot's BOM, or specify one --></dependency><!-- Eclipse Paho MQTT Client (Spring Integration MQTT uses this) --><dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.5</version> <!-- Or a newer compatible version --></dependency>
</dependencies>

步驟 2:配置 MQTT 連接屬性

src/main/resources/application.properties (或 application.yml) 中配置 MQTT Broker 的連接信息:

# MQTT Broker Configuration
mqtt.broker.url=tcp://localhost:1883
mqtt.client.id.publisher=springBootPublisher-unique # 客戶端ID,對于每個連接必須唯一
mqtt.client.id.subscriber=springBootSubscriber-unique # 客戶端ID,對于每個連接必須唯一
mqtt.default.topic=test/topic
mqtt.qos=1 # 默認的服務質量等級 (0, 1, or 2)# 可選:如果 Broker 需要認證
# mqtt.username=your_username
# mqtt.password=your_password

注意:Client ID 在 MQTT 中必須是唯一的。如果應用同時發布和訂閱,可能需要為發布者和訂閱者使用不同的 Client ID,或者使用一個 Client ID 但要確保 Paho 客戶端實例的正確性。

步驟 3:創建 MQTT 配置類

創建一個 Java 配置類來定義 MQTT 相關的 Bean,如 ClientFactory、出站適配器(用于發布消息)和入站適配器(用于訂閱消息)。

package com.example.mqttdemo.config;import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
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.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.outbound.MqttPahoMessageHandler;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.handler.annotation.Header;@Configuration
@IntegrationComponentScan // 掃描 @MessagingGateway 等注解
public class MqttConfig {private static final Logger LOGGER = LoggerFactory.getLogger(MqttConfig.class);@Value("${mqtt.broker.url}")private String brokerUrl;@Value("${mqtt.client.id.publisher}")private String publisherClientId;@Value("${mqtt.client.id.subscriber}")private String subscriberClientId;@Value("${mqtt.default.topic}")private String defaultTopic;@Value("${mqtt.qos}")private int defaultQos;// 可選: 如果需要用戶名密碼認證// @Value("${mqtt.username}")// private String username;// @Value("${mqtt.password}")// private String password;// --- 通用 MQTT Client Factory ---@Beanpublic MqttPahoClientFactory mqttClientFactory() {DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();MqttConnectOptions options = new MqttConnectOptions();options.setServerURIs(new String[]{brokerUrl});// if (username != null && !username.isEmpty()) {//     options.setUserName(username);// }// if (password != null && !password.isEmpty()) {//     options.setPassword(password.toCharArray());// }options.setCleanSession(true); // 設置為 false 以啟用持久會話和離線消息options.setAutomaticReconnect(true); // 啟用自動重連options.setConnectionTimeout(10); // 連接超時時間 (秒)options.setKeepAliveInterval(20); // 心跳間隔 (秒)factory.setConnectionOptions(options);return factory;}// --- MQTT 消息發布 (Outbound) ---@Beanpublic MessageChannel mqttOutboundChannel() {return new DirectChannel(); // 或者 PublishSubscribeChannel}@Bean@ServiceActivator(inputChannel = "mqttOutboundChannel")public MessageHandler mqttOutbound(MqttPahoClientFactory clientFactory) {MqttPahoMessageHandler messageHandler =new MqttPahoMessageHandler(publisherClientId, clientFactory); // 使用獨立的 Client IDmessageHandler.setAsync(true); // 推薦異步發送messageHandler.setDefaultTopic(defaultTopic); // 默認主題,可以被消息頭覆蓋messageHandler.setDefaultQos(defaultQos); // 默認QoS,可以被消息頭覆蓋// messageHandler.setDefaultRetained(false); // 默認是否保留消息return messageHandler;}// 定義一個網關接口,用于發送消息到 mqttOutboundChannel// Spring Integration 會自動實現這個接口@MessagingGateway(defaultRequestChannel = "mqttOutboundChannel")public interface MqttGateway {void sendToMqtt(String payload);void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, String payload);void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, @Header(MqttHeaders.QOS) int qos, String payload);// 可以定義更多重載方法,例如發送 byte[]// void sendToMqtt(@Header(MqttHeaders.TOPIC) String topic, byte[] payload);}// --- MQTT 消息訂閱 (Inbound) ---@Beanpublic MessageChannel mqttInputChannel() {return new DirectChannel();}@Beanpublic MqttPahoMessageDrivenChannelAdapter inboundAdapter(MqttPahoClientFactory clientFactory) {// 可以訂閱單個主題,或多個主題 (字符串數組)// String[] topicsToSubscribe = {defaultTopic, "another/topic", "sensor/+/data"};MqttPahoMessageDrivenChannelAdapter adapter =new MqttPahoMessageDrivenChannelAdapter(subscriberClientId, clientFactory, defaultTopic); // 使用獨立的 Client IDadapter.setCompletionTimeout(5000); // 等待消息發送完成的超時時間adapter.setConverter(new DefaultPahoMessageConverter()); // 消息轉換器adapter.setQos(defaultQos); // 訂閱時的QoSadapter.setOutputChannel(mqttInputChannel()); // 將接收到的消息發送到此 Channelreturn adapter;}// 消息處理器,處理從 mqttInputChannel 接收到的消息@ServiceActivator(inputChannel = "mqttInputChannel")public void handleIncomingMqttMessage(org.springframework.messaging.Message<String> message) {String topic = message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC, String.class);String payload = message.getPayload();Integer qos = message.getHeaders().get(MqttHeaders.RECEIVED_QOS, Integer.class);Boolean retained = message.getHeaders().get(MqttHeaders.RETAINED, Boolean.class);LOGGER.info("Received MQTT Message - Topic: [{}], QoS: [{}], Retained: [{}], Payload: [{}]",topic, qos, retained, payload);// 在這里處理你的業務邏輯}// 可選: 監聽 MQTT 事件 (連接成功,連接丟失等)/*@EventListenerpublic void handleMqttEvents(MqttIntegrationEvent event) {LOGGER.info("MQTT Event: {}", event);if (event instanceof MqttConnectionFailedEvent) {MqttConnectionFailedEvent failedEvent = (MqttConnectionFailedEvent) event;LOGGER.error("MQTT Connection Failed!", failedEvent.getCause());} else if (event instanceof MqttSubscribedEvent) {MqttSubscribedEvent subscribedEvent = (MqttSubscribedEvent) event;LOGGER.info("MQTT Subscribed to: {}", subscribedEvent.getMessage());}//還有 MqttMessageSentEvent, MqttMessageDeliveredEvent 等}*/
}

解釋:

  1. MqttPahoClientFactory:

    • 創建和配置底層的 Paho MQTT 客戶端。
    • MqttConnectOptions 用于設置 Broker URL、用戶名/密碼、Clean Session、Keep Alive、自動重連等。
    • setCleanSession(true): 每次連接都是一個全新的會話,斷開后 Broker 不會保留訂閱信息和離線消息。
    • setCleanSession(false): 持久會話,客戶端斷開重連后,Broker 會嘗試發送離線期間的 QoS 1 和 QoS 2 消息,并恢復訂閱。需要 Client ID 保持不變。
  2. 發布消息 (Outbound):

    • mqttOutboundChannel: 一個 MessageChannel,作為消息發布的入口。
    • MqttPahoMessageHandler (mqttOutbound bean): 這是一個 MessageHandler,它監聽 mqttOutboundChannel,并將接收到的消息通過 MQTT 發送出去。
      • 需要一個 clientIdMqttPahoClientFactory
      • setAsync(true): 異步發送消息,不會阻塞當前線程。
      • setDefaultTopic()setDefaultQos(): 如果消息本身沒有指定主題或QoS,則使用這些默認值。
    • MqttGateway: 一個接口,使用 @MessagingGateway 注解。Spring Integration 會自動為其生成實現。通過調用這個接口的方法,可以方便的將消息發送到 defaultRequestChannel (即 mqttOutboundChannel)。
      • @Header(MqttHeaders.TOPIC)@Header(MqttHeaders.QOS) 允許在發送時動態指定主題和QoS。
  3. 訂閱消息 (Inbound):

    • mqttInputChannel: 一個 MessageChannel,入站適配器會將從 MQTT Broker 收到的消息發送到這個 Channel。
    • MqttPahoMessageDrivenChannelAdapter (inboundAdapter bean): 這是一個消息驅動的通道適配器,它連接到 MQTT Broker,訂閱指定的主題,并將收到的消息推送到 outputChannel (即 mqttInputChannel)。
      • 需要一個 clientIdMqttPahoClientFactory 和要訂閱的主題(可以是一個或多個,支持通配符)。
      • setConverter(): 用于將 MQTT 的 byte[] 負載轉換為期望的類型(例如 String)。DefaultPahoMessageConverter 可以處理 Stringbyte[]
    • handleIncomingMqttMessage 方法: 使用 @ServiceActivator(inputChannel = "mqttInputChannel") 注解,監聽 mqttInputChannel。當有消息到達時,此方法會被調用。
      • message.getHeaders().get(MqttHeaders.RECEIVED_TOPIC): 獲取消息來源的主題。
      • message.getPayload(): 獲取消息內容。
  4. @IntegrationComponentScan: 確保 Spring Integration 掃描并處理 @MessagingGateway 等注解。

步驟 4:使用 MQTT Gateway 發布消息

你可以注入 MqttGateway 到你的 Service 或 Controller 中來發送消息。

示例 Service:

package com.example.mqttdemo.service;import com.example.mqttdemo.config.MqttConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MqttPublishService {private static final Logger LOGGER = LoggerFactory.getLogger(MqttPublishService.class);@Autowiredprivate MqttConfig.MqttGateway mqttGateway;public void publishMessage(String topic, String payload) {try {LOGGER.info("Publishing MQTT message - Topic: [{}], Payload: [{}]", topic, payload);mqttGateway.sendToMqtt(topic, payload);} catch (Exception e) {LOGGER.error("Error publishing MQTT message to topic {}: {}", topic, e.getMessage(), e);}}public void publishMessageWithQos(String topic, String payload, int qos) {try {LOGGER.info("Publishing MQTT message - Topic: [{}], QoS: [{}], Payload: [{}]", topic, qos, payload);mqttGateway.sendToMqtt(topic, qos, payload);} catch (Exception e) {LOGGER.error("Error publishing MQTT message to topic {} with QoS {}: {}", topic, qos, e.getMessage(), e);}}public void publishToDefaultTopic(String payload) {try {LOGGER.info("Publishing MQTT message to default topic, Payload: [{}]", payload);mqttGateway.sendToMqtt(payload); // 將使用 MqttPahoMessageHandler 中配置的默認主題和QoS} catch (Exception e) {LOGGER.error("Error publishing MQTT message to default topic: {}", e.getMessage(), e);}}
}

示例 REST Controller (可選):

package com.example.mqttdemo.controller;import com.example.mqttdemo.service.MqttPublishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/api/mqtt")
public class MqttController {@Autowiredprivate MqttPublishService mqttPublishService;@PostMapping("/publish")public String publishMessage(@RequestParam String topic, @RequestBody String payload) {mqttPublishService.publishMessage(topic, payload);return "Message published to topic: " + topic;}@PostMapping("/publish-default")public String publishToDefault(@RequestBody String payload) {mqttPublishService.publishToDefaultTopic(payload);return "Message published to default topic.";}@PostMapping("/publish-qos")public String publishMessageWithQos(@RequestParam String topic,@RequestParam int qos,@RequestBody String payload) {mqttPublishService.publishMessageWithQos(topic, payload, qos);return "Message published to topic: " + topic + " with QoS: " + qos;}
}

步驟 5:運行和測試

  1. 啟動 MQTT Broker (例如,使用 Docker 運行 Mosquitto):
    docker run -it -p 1883:1883 -p 9001:9001 eclipse-mosquitto
    
  2. 運行 Spring Boot 應用
  3. 測試發布
    • 如果創建了 REST Controller,可以通過 Postman 或 curl 發送 POST 請求:
      POST http://localhost:8080/api/mqtt/publish?topic=my/custom/topic
      Body (raw, text/plain): Hello from Spring Boot MQTT!
    • 或者在應用啟動時通過 CommandLineRunner 調用 MqttPublishService
  4. 測試訂閱
    • 當有消息發布到應用訂閱的主題 (例如 test/topic 或在 inboundAdapter 中配置的其他主題) 時,handleIncomingMqttMessage 方法會被調用,在控制臺能看到日志輸出。
    • 也可以使用 MQTT 客戶端工具 (如 MQTTX, MQTT Explorer) 連接到同一個 Broker 并發布消息到被訂閱的主題。

高級主題和注意事項:

  • QoS (服務質量等級)
    • QoS 0 (At most once): 最多一次,消息可能丟失。
    • QoS 1 (At least once): 至少一次,消息可能重復。
    • QoS 2 (Exactly once): 精確一次,最可靠但開銷最大。
    • 可以在 MqttPahoMessageHandlerMqttPahoMessageDrivenChannelAdapter 中設置默認 QoS,也可以在發送消息時通過 MqttHeaders.QOS 動態指定。
  • Retained Messages (保留消息)
    • 發布者可以將消息標記為 “retained”。Broker 會存儲該主題下最新的保留消息。當新客戶端訂閱該主題時,會立即收到這條保留消息。
    • MqttPahoMessageHandler 中設置 setDefaultRetained(true) 或通過消息頭 MqttHeaders.RETAINED
  • Last Will and Testament (LWT - 遺囑消息)
    • MqttConnectOptions 中配置。如果客戶端異常斷開,Broker 會發布這個預設的遺囑消息到指定主題。
    • options.setWill("client/status", "offline".getBytes(), 1, false);
  • SSL/TLS 加密
    • 如果 Broker 使用 SSL/TLS,需要在 MqttConnectOptions 中配置 SSL 屬性,并將 Broker URL 改為 ssl://your-broker-address:8883
    • options.setSocketFactory(SslUtil.getSocketFactory("ca.crt", "client.crt", "client.key", "password")); (需要相應的證書文件和密碼)
  • 錯誤處理
    • Spring Integration 提供了錯誤通道 (errorChannel) 來處理消息傳遞過程中的異常。
    • 可以監聽 MqttIntegrationEvent (如 MqttConnectionFailedEvent) 來獲取連接狀態事件。
  • Client ID 唯一性:再次強調,連接到同一個 Broker 的每個 MQTT 客戶端都必須有唯一的 Client ID。如果發布和訂閱邏輯在同一個應用實例中,并且為它們配置了相同的 Client ID 但使用了不同的 MqttPahoClientFactory 實例或適配器,Paho 庫內部可能會產生沖突或意外行為。建議為出站和入站適配器使用不同的 Client ID,或者共享一個 MqttPahoClientFactory 實例(確保它能正確處理這種情況)。
  • Converter (轉換器): DefaultPahoMessageConverter 默認將 String 轉換為 byte[] 發送,接收時根據目標類型嘗試轉換。如果需要處理 JSON 或其他復雜類型,需要自定義 MessageConverter 或在消息處理器中進行序列化/反序列化。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83052.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

養生:為健康生活注入活力

在快節奏的現代生活中&#xff0c;養生不再是老年人的專屬&#xff0c;而是每個人維持身心健康的必修課。從飲食到運動&#xff0c;從睡眠到心態&#xff0c;全方位的養生方式能幫助我們抵御壓力&#xff0c;擁抱充滿活力的生活。 飲食養生&#xff1a;合理搭配&#xff0c;滋…

Axure設計之內聯框架切換頁面、子頁面間跳轉問題

在Axure中&#xff0c;你可以通過以下步驟實現主頁面中的內聯框架在點擊按鈕時切換頁面內容&#xff0c;從A頁面切換到B頁面。&#xff08;誤區&#xff1a;子頁面之間切換不要設置“框架中打開鏈接”然后選“父級框架”這個交互&#xff09; 主框架頁面&#xff08;左側導航展…

[思維模式-38]:看透事物的關系:什么是事物的關系?事物之間的關系的種類?什么是因果關系?如何通過數學的方式表達因果關系?

一、什么是事物的關系&#xff1f; 事物的關系是指不同事物之間存在的各種聯系和相互作用&#xff0c;它反映了事物之間的相互依存、相互影響、相互制約等特性。以下從不同維度為你詳細闡述&#xff1a; 1、關系的類型 因果關系 定義&#xff1a;一個事件&#xff08;原因&a…

OJ判題系統第6期之判題邏輯開發——設計思路、實現步驟、代碼實現(策略模式)

在看這期之前&#xff0c;建議先看前五期&#xff1a; Java 原生實現代碼沙箱&#xff08;OJ判題系統第1期&#xff09;——設計思路、實現步驟、代碼實現-CSDN博客 Java 原生實現代碼沙箱之Java 程序安全控制&#xff08;OJ判題系統第2期&#xff09;——設計思路、實現步驟…

行業趨勢與技術創新:駕馭工業元宇宙與綠色智能制造

引言 制造業發展的新格局&#xff1a;創新勢在必行 當今制造業正經歷深刻變革&#xff0c;面臨著供應鏈波動、個性化需求增長、可持續發展壓力以及技能人才短缺等多重挑戰。在這樣的背景下&#xff0c;技術創新不再是可有可無的選項&#xff0c;而是企業保持競爭力、實現可持…

高效Python開發:uv包管理器全面解析

目錄 uv簡介亮點與 pip、pip-tools、pipx、poetry、pyenv、virtualenv 對比 安裝uv快速開始uv安裝pythonuv運行腳本運行無依賴的腳本運行有依賴的腳本創建帶元數據的 Python 腳本使用 shebang 創建可執行文件使用其他package indexes鎖定依賴提高可復現性指定不同的 Python 版本…

鴻蒙OSUniApp開發富文本編輯器組件#三方框架 #Uniapp

使用UniApp開發富文本編輯器組件 富文本編輯在各類應用中非常常見&#xff0c;無論是內容創作平臺還是社交軟件&#xff0c;都需要提供良好的富文本編輯體驗。本文記錄了我使用UniApp開發一個跨平臺富文本編輯器組件的過程&#xff0c;希望對有類似需求的開發者有所啟發。 背景…

字符串檢索算法:KMP和Trie樹

目錄 1.引言 2.KMP算法 3.Trie樹 3.1.簡介 3.2.Trie樹的應用場景 3.3.復雜度分析 3.4.Trie 樹的優缺點 3.5.示例 1.引言 字符串匹配&#xff0c;給定一個主串 S 和一個模式串 P&#xff0c;判斷 P 是否是 S 的子串&#xff0c;即找到 P 在 S 中第一次出現的位置。暴力匹…

計算機組成原理:I/O

計算機組成:I/O I/O概述I/O系統構成I/O接口I/O端口兩種編址區分I/O數據傳送控制方式程序查詢方式獨占查詢中斷控制方式硬件判優法(向量中斷法)多重中斷嵌套DMA控制方式三種DMA方式DMA操作步驟內部異常和中斷異常和中斷的關系I/O概述 I/O系統構成 一個最基礎I/O系統的構成:CPU…

ssti模板注入學習

ssti模板注入原理 ssti模板注入是一種基于服務器的模板引擎的特性和漏洞產生的一種漏洞&#xff0c;通過將而已代碼注入模板中實現的服務器的攻擊 模板引擎 為什么要有模板引擎 在web開發中&#xff0c;為了使用戶界面與業務數據&#xff08;內容&#xff09;分離而產生的&…

NVMe簡介2

共分2部分&#xff0c;這里是第2部分。 NVMe數據結構 NVMe協議中規定每個提交命令的大小為64字節&#xff0c;完成命令大小為16字節&#xff0c;NVMe命令分為Admin和IO兩類&#xff0c;NVMe的數據塊組織方式有PRP和SGL兩種。提交命令的格式如圖5所示。 圖5 提交命令數據格 N…

高壓啟動電路--學習記錄

常見反激的啟動電路 優點&#xff1a;電路設計簡單&#xff0c;價格便宜 缺點&#xff1a;損壞大&#xff0c;輸入寬范圍的時候&#xff0c;為了保證低壓能正常啟動&#xff0c;啟動電阻阻值需要選小&#xff0c;那么高壓時損耗會非常大&#xff0c;設計的不好很容易在高壓時損…

VS打印printf、cout或者Qt的qDebug等傳出的打印信息

在vs中打印printf、cout或者Qt的qDebug等常見的打印信息有時也是必要的&#xff0c;簡單的敘述一下過程&#xff1a; 1、在vs中打開你的解決方案。 2、鼠標移動到你的項目名稱上&#xff0c;點擊鼠標右鍵&#xff0c;再點擊屬性&#xff0c;此刻會此項目的屬性頁。 3、在配置…

蒼穹外賣--新增菜品

1.需求分析和設計 產品原型 業務規則&#xff1a; 菜品名稱必須是唯一的 菜品必須屬于某個分類下&#xff0c;不能單獨存在 新增菜品時可以根據情況選擇菜品的口味 每個菜品必須對應一張圖片 接口設計&#xff1a; 根據類型查詢分類(已完成) 文件上傳 新增菜品 根據類型…

如何高效集成MySQL數據到金蝶云星空

MySQL數據集成到金蝶云星空&#xff1a;SC采購入庫-深圳天一-OK案例分享 在企業信息化建設中&#xff0c;數據的高效流轉和準確對接是實現業務流程自動化的關鍵。本文將聚焦于一個具體的系統對接集成案例——“SC采購入庫-深圳天一-OK”&#xff0c;詳細探討如何通過輕易云數據…

【springcloud學習(dalston.sr1)】使用Feign實現接口調用(八)

該系列項目整體介紹及源代碼請參照前面寫的一篇文章【springcloud學習(dalston.sr1)】項目整體介紹&#xff08;含源代碼&#xff09;&#xff08;一&#xff09; &#xff08;一&#xff09;Feign的理解 前面文章【springcloud學習(dalston.sr1)】服務消費者通過restTemplat…

SpringbBoot nginx代理獲取用戶真實IP

為了演示多級代理場景&#xff0c;我們分配了以下服務器資源&#xff1a; 10.1.9.98&#xff1a;充當客戶端10.0.3.137&#xff1a;一級代理10.0.4.105&#xff1a;二級代理10.0.4.129&#xff1a;三級代理10.0.4.120&#xff1a;服務器端 各級代理配置 以下是各級代理的基本配…

實驗九視圖索引

設計性實驗 1. 創建視圖V_A包括學號&#xff0c;姓名&#xff0c;性別&#xff0c;課程號&#xff0c;課程名、成績&#xff1b; 一個語句把學號103 課程號3-105 的姓名改為陸君茹1&#xff0c;性別為女 &#xff0c;然后查看學生表的信息變化&#xff0c;再把上述數據改為原…

typeof運算符和深拷貝

typeof運算符 識別所有值類型識別函數判斷是否是引用類型&#xff08;不可再細分&#xff09; //判斷所有值類型 let a; typeof a //undefined const strabc; typeof str //string const n100; typeof n //number const …

NAT/代理服務器/內網穿透

目錄 一 NAT技術 二 內網穿透/內網打洞 三 代理服務器 一 NAT技術 跨網絡傳輸的時候&#xff0c;私網不能直接訪問公網&#xff0c;就引入了NAT能講私網轉換為公網進行訪問&#xff0c;主要解決IPv4(2^32)地址不足的問題。 1. NAT原理 當某個內網想訪問公網&#xff0c;就必…