SpringBoot中的@MessageMapping注解详解
作者:2013crazy
@MessageMapping
随着 Web 技术的发展,越来越多的应用程序开始使用 WebSocket 协议来实现实时通信。
Spring Boot 提供了对 WebSocket 的支持,其中 @MessageMapping 注解是一个常用的注解,它可以将一个 Java 方法标记为 WebSocket 的消息处理器。
本文将介绍 Spring Boot 中 @MessageMapping 注解的原理、用法和示例。
@MessageMapping 注解的原理
在 Spring Boot 中,@MessageMapping 注解用于标识一个 Java 方法是一个 WebSocket 消息处理器。
消息处理器负责接收客户端发送的消息,并进行处理。具体来说,使用 @MessageMapping 注解的方法将会被 Spring WebSocket 自动扫描,并注册为一个消息处理器。
@MessageMapping 注解的作用类似于 @RequestMapping 注解,但是它只能用于 WebSocket 消息处理器。
使用 @MessageMapping 注解时,需要指定消息的目的地(Destination),即客户端发送消息时的目标地址。
@MessageMapping 注解的用法
使用 @MessageMapping 注解的步骤如下:
1. 创建 WebSocket 配置类
首先,需要创建一个 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(); } }
上面的代码中,创建了一个 WebSocketHandlerRegistry 对象,并将 ChatHandler() 的实例注册为 /chat 的处理器。
2. 创建消息处理器类
在消息处理器类中,需要编写消息处理器方法。消息处理器方法处理客户端发送的消息,并返回响应。消息处理器方法可以使用 Spring WebSocket 提供的注解来指定消息的目的地、消息的类型和其他参数。
@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。方法的参数中,String 类型的 message 表示客户端发送的消息内容。方法的返回值为 void,表示不需要返回响应。
3. 启动应用程序
最后,需要启动应用程序,并访问 ws://localhost:8080/chat,就可以开始使用 WebSocket 了。
@SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } }
@MessageMapping 注解的示例
下面是一个使用 @MessageMapping 注解的示例项目。
1. 创建项目
使用 Spring Initializr 创建一个新的 Spring Boot 项目,添加以下依赖:
- Spring Websocket
- Thymeleaf
2. 创建 WebSocket 配置类
创建一个 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(); } }
上面的代码中,创建了一个 WebSocketHandlerRegistry 对象,并将 ChatHandler() 的实例注册为 /chat 的处理器。使用 withSockJS() 方法可以启用 SockJS 支持。
3. 创建消息处理器类
在消息处理器类中,需要编写消息处理器方法。消息处理器方法处理客户端发送的消息,并返回响应。消息处理器方法可以使用 Spring WebSocket 提供的注解来指定消息的目的地、消息的类型和其他参数。
@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。方法的参数中,ChatMessage 类型的 message 表示客户端发送的消息内容。方法的返回值为 void,表示不需要返回响应。使用 sessions 列表来存储所有连接的 WebSocketSession。
同时,还实现了 afterConnectionEstablished()、handleTransportError() 和 afterConnectionClosed() 方法,分别用于处理连接建立、传输错误和连接关闭的事件。broadcast() 方法用于向所有 WebSocketSession 广播消息。
4. 创建 Thymeleaf 模板文件
在 src/main/resources/templates 目录下,创建一个名为 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 协议来实现 WebSocket 的兼容性。同时,引入了 chat.js 文件,用于处理客户端发送消息和接收消息的逻辑。
5. 创建客户端脚本文件
在 src/main/resources/static/js 目录下,创建一个名为 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() 方法创建一个 STOMP 客户端对象。使用 stompClient.connect() 方法来连接到 WebSocket 服务器,并使用 stompClient.subscribe() 方法来订阅 /topic/messages 目的地,以接收广播消息。
使用 sendMessage() 方法来发送消息。该方法将 name 和 message 作为 JSON 对象发送到 /app/chat 目的地。
使用 showMessage() 方法来显示消息。该方法将消息添加到 messages 元素中。
6. 运行应用程序
最后,运行应用程序,访问 //localhost:8080/chat,就可以开始使用聊天功能了。
总结
本文介绍了 Spring Boot 中 @MessageMapping 注解的原理、用法和示例。通过使用 @MessageMapping 注解,可以很方便地编写 WebSocket 消息处理器,实现实时通信功能。
到此这篇关于SpringBoot中的@MessageMapping注解详解的文章就介绍到这了,更多相关SpringBoot的@MessageMapping内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!