SpringBoot中的@MessageMapping注解詳解
@MessageMapping
隨著 Web 技術(shù)的發(fā)展,越來越多的應(yīng)用程序開始使用 WebSocket 協(xié)議來實(shí)現(xiàn)實(shí)時(shí)通信。
Spring Boot 提供了對(duì) WebSocket 的支持,其中 @MessageMapping 注解是一個(gè)常用的注解,它可以將一個(gè) Java 方法標(biāo)記為 WebSocket 的消息處理器。
本文將介紹 Spring Boot 中 @MessageMapping 注解的原理、用法和示例。
@MessageMapping 注解的原理
在 Spring Boot 中,@MessageMapping 注解用于標(biāo)識(shí)一個(gè) Java 方法是一個(gè) WebSocket 消息處理器。
消息處理器負(fù)責(zé)接收客戶端發(fā)送的消息,并進(jìn)行處理。具體來說,使用 @MessageMapping 注解的方法將會(huì)被 Spring WebSocket 自動(dòng)掃描,并注冊(cè)為一個(gè)消息處理器。
@MessageMapping 注解的作用類似于 @RequestMapping 注解,但是它只能用于 WebSocket 消息處理器。
使用 @MessageMapping 注解時(shí),需要指定消息的目的地(Destination),即客戶端發(fā)送消息時(shí)的目標(biāo)地址。
@MessageMapping 注解的用法
使用 @MessageMapping 注解的步驟如下:
1. 創(chuàng)建 WebSocket 配置類
首先,需要?jiǎng)?chuàng)建一個(gè) WebSocket 配置類,并添加 @EnableWebSocket 注解。該注解用于啟用 Spring WebSocket。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(chatHandler(), "/chat");
}
@Bean
public WebSocketHandler chatHandler() {
return new ChatHandler();
}
}上面的代碼中,創(chuàng)建了一個(gè) WebSocketHandlerRegistry 對(duì)象,并將 ChatHandler() 的實(shí)例注冊(cè)為 /chat 的處理器。
2. 創(chuàng)建消息處理器類
在消息處理器類中,需要編寫消息處理器方法。消息處理器方法處理客戶端發(fā)送的消息,并返回響應(yīng)。消息處理器方法可以使用 Spring WebSocket 提供的注解來指定消息的目的地、消息的類型和其他參數(shù)。
@Component
public class ChatHandler implements WebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("Connection established: " + session.getId());
}
@MessageMapping("/hello")
public void handleHelloMessage(String message) {
System.out.println("Received message: " + message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("Transport error: " + exception.getMessage());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("Connection closed: " + session.getId());
}
@Override
public boolean supportsPartialMessages() {
return false;
}
}上面的代碼中,@MessageMapping 注解用于指定消息的目的地,即 /hello。方法的參數(shù)中,String 類型的 message 表示客戶端發(fā)送的消息內(nèi)容。方法的返回值為 void,表示不需要返回響應(yīng)。
3. 啟動(dòng)應(yīng)用程序
最后,需要啟動(dòng)應(yīng)用程序,并訪問 ws://localhost:8080/chat,就可以開始使用 WebSocket 了。
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}@MessageMapping 注解的示例
下面是一個(gè)使用 @MessageMapping 注解的示例項(xiàng)目。
1. 創(chuàng)建項(xiàng)目
使用 Spring Initializr 創(chuàng)建一個(gè)新的 Spring Boot 項(xiàng)目,添加以下依賴:
- Spring Websocket
- Thymeleaf
2. 創(chuàng)建 WebSocket 配置類
創(chuàng)建一個(gè) WebSocketConfig 類,并添加 @EnableWebSocket 注解。該注解用于啟用 Spring WebSocket。
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(chatHandler(), "/chat").withSockJS();
}
@Bean
public WebSocketHandler chatHandler() {
return new ChatHandler();
}
}上面的代碼中,創(chuàng)建了一個(gè) WebSocketHandlerRegistry 對(duì)象,并將 ChatHandler() 的實(shí)例注冊(cè)為 /chat 的處理器。使用 withSockJS() 方法可以啟用 SockJS 支持。
3. 創(chuàng)建消息處理器類
在消息處理器類中,需要編寫消息處理器方法。消息處理器方法處理客戶端發(fā)送的消息,并返回響應(yīng)。消息處理器方法可以使用 Spring WebSocket 提供的注解來指定消息的目的地、消息的類型和其他參數(shù)。
@Component
public class ChatHandler implements WebSocketHandler {
private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println("Connection established: " + session.getId());
sessions.add(session);
broadcast("User " + session.getId() + " joined the chat");
}
@MessageMapping("/chat")
public void handleChatMessage(ChatMessage message) {
System.out.println("Received message: " + message);
broadcast(message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
System.out.println("Transport error: " + exception.getMessage());
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
System.out.println("Connection closed: " + session.getId() + " (" + closeStatus.getCode() + ")");
sessions.remove(session);
broadcast("User " + session.getId() + " left the chat");
}
@Override
public boolean supportsPartialMessages() {
return false;
}
private void broadcast(Object message) {
for (WebSocketSession session : sessions) {
try {
session.sendMessage(new TextMessage(new ObjectMapper().writeValueAsString(message)));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}上面的代碼中,@MessageMapping 注解用于指定消息的目的地,即 /chat。方法的參數(shù)中,ChatMessage 類型的 message 表示客戶端發(fā)送的消息內(nèi)容。方法的返回值為 void,表示不需要返回響應(yīng)。使用 sessions 列表來存儲(chǔ)所有連接的 WebSocketSession。
同時(shí),還實(shí)現(xiàn)了 afterConnectionEstablished()、handleTransportError() 和 afterConnectionClosed() 方法,分別用于處理連接建立、傳輸錯(cuò)誤和連接關(guān)閉的事件。broadcast() 方法用于向所有 WebSocketSession 廣播消息。
4. 創(chuàng)建 Thymeleaf 模板文件
在 src/main/resources/templates 目錄下,創(chuàng)建一個(gè)名為 chat.html 的 Thymeleaf 模板文件。
<!DOCTYPE html>
<html>
<head>
<title>Chat</title>
<script src="/webjars/sockjs-client/1.5.0/dist/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/2.3.3/dist/stomp.min.js"></script>
<script src="/js/chat.js"></script>
</head>
<body>
<h1>Chat</h1>
<form onsubmit="return false;">
<input type="text" id="name" placeholder="Name">
<input type="text" id="message" placeholder="Message">
<button onclick="sendMessage()">Send</button>
</form>
<div id="messages"></div>
</body>
</html>上面的代碼中,使用了 SockJS 和 STOMP 協(xié)議來實(shí)現(xiàn) WebSocket 的兼容性。同時(shí),引入了 chat.js 文件,用于處理客戶端發(fā)送消息和接收消息的邏輯。
5. 創(chuàng)建客戶端腳本文件
在 src/main/resources/static/js 目錄下,創(chuàng)建一個(gè)名為 chat.js 的客戶端腳本文件。
var stompClient = null;
function connect() {
var socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/messages', function (message) {
showMessage(JSON.parse(message.body));
});
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
console.log("Disconnected");
}
function sendMessage() {
var name = document.getElementById('name').value;
var message = document.getElementById('message').value;
stompClient.send("/app/chat", {}, JSON.stringify({'name': name, 'message': message}));
}
function showMessage(message) {
var div = document.createElement('div');
div.appendChild(document.createTextNode(message.name + ': ' + message.message));
document.getElementById('messages').appendChild(div);
}
connect();上面的代碼中,使用 connect() 方法來建立 WebSocket 連接。使用Stomp.over() 方法創(chuàng)建一個(gè) STOMP 客戶端對(duì)象。使用 stompClient.connect() 方法來連接到 WebSocket 服務(wù)器,并使用 stompClient.subscribe() 方法來訂閱 /topic/messages 目的地,以接收廣播消息。
使用 sendMessage() 方法來發(fā)送消息。該方法將 name 和 message 作為 JSON 對(duì)象發(fā)送到 /app/chat 目的地。
使用 showMessage() 方法來顯示消息。該方法將消息添加到 messages 元素中。
6. 運(yùn)行應(yīng)用程序
最后,運(yùn)行應(yīng)用程序,訪問 //localhost:8080/chat,就可以開始使用聊天功能了。
總結(jié)
本文介紹了 Spring Boot 中 @MessageMapping 注解的原理、用法和示例。通過使用 @MessageMapping 注解,可以很方便地編寫 WebSocket 消息處理器,實(shí)現(xiàn)實(shí)時(shí)通信功能。
到此這篇關(guān)于SpringBoot中的@MessageMapping注解詳解的文章就介紹到這了,更多相關(guān)SpringBoot的@MessageMapping內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python輸入輸出從鍵盤到文件實(shí)戰(zhàn)全面指南
這篇文章主要為大家介紹了Python輸入輸出從鍵盤到文件實(shí)戰(zhàn)全面指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11
Python編程中NotImplementedError的使用方法
下面小編就為大家分享一篇Python編程中NotImplementedError的使用方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-04-04
python pcm音頻添加頭轉(zhuǎn)成Wav格式文件的方法
今天小編就為大家分享一篇python pcm音頻添加頭轉(zhuǎn)成Wav格式文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01
基于Python實(shí)現(xiàn)在控制臺(tái)查看excel的內(nèi)容
這篇文章主要為大家詳細(xì)介紹了如何基于Python實(shí)現(xiàn)在控制臺(tái)查看excel的內(nèi)容,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12
python 遞歸深度優(yōu)先搜索與廣度優(yōu)先搜索算法模擬實(shí)現(xiàn)
這篇文章主要介紹了python 遞歸深度優(yōu)先搜索與廣度優(yōu)先搜索算法模擬實(shí)現(xiàn) ,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-10-10

