java websocket 404_Spring WebSocket 404错误的解决方法

近来学习 Spring WebSocket 时按照 Spring IN ACTION 中示例编写代码,运行时浏览器报404 错误

WebSocket connection to 'ws://localhost/websocket/marco' failed: Error during WebSocket handshake: Unexpected response code: 404

8e59f5e7ffbf74c1c6bc7a328da8833f.png

按照 Spring IN ACTION 中步骤:

首先,继承 AbstractWebSocketHandler,重载以下 3 个方法:

- handleTextMessage – 处理文本类型消息

- afterConnectionEstablished – 新连接建立后调用

- afterConnectionClosed – 连接关闭后调用

import org.springframework.web.socket.CloseStatus;

import org.springframework.web.socket.TextMessage;

import org.springframework.web.socket.WebSocketSession;

import org.springframework.web.socket.handler.AbstractWebSocketHandler;

public class MarcoHandler extends AbstractWebSocketHandler {

protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

System.out.println("Received message: " + message.getPayload());

Thread.sleep(2000);

session.sendMessage(new TextMessage("Polo!"));

}

@Override

public void afterConnectionEstablished(WebSocketSession session) {

System.out.println("Connection established!");

}

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {

System.out.println("Connection closed. Status: " + status);

}

}

其次,使用 JavaConfig 启用 WebSocket 并映射消息处理器

import org.springframework.context.annotation.Bean;

import org.springframework.web.socket.config.annotation.EnableWebSocket;

import org.springframework.web.socket.config.annotation.WebSocketConfigurer;

import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@EnableWebSocket

public class WebSocketConfig implements WebSocketConfigurer {

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

registry.addHandler(marcoHandler(), "/marco");

}

@Bean

public MarcoHandler marcoHandler() {

return new MarcoHandler();

}

}

最后,编写前端 JS 代码发起连接请求及后续消息交互

var url = 'ws://' + window.location.host + '/websocket/marco';

var sock = new WebSocket(url);

sock.onopen = function() {

console.log('Opening');

sock.send('Marco!');

};

sock.onmessage = function(e) {

console.log('Received Message: ', e.data);

setTimeout(function() {

sayMarco()

}, 2000);

};

sock.onclose = function() {

console.log('Closing');

};

function sayMarco() {

console.log('Sending Marco!');

sock.send('Marco!');

}

部署后打开浏览器运行,直接报 404 错误

566636d5c822678ee761af26d1fe0d35.png

上网搜索了一晚上解决方案,包括参考 stackoverflow.com 上的经验都未解决该问题,直到查看到以下文章:

Spring集成webSocket页面访问404问题的解决方法

在此自己也做个记录避免以后遗忘。

WebSocket 实质上借用 HTTP 请求进行握手,启用 Spring WebSocket 需要在org.springframework.web.servlet.DispatcherServlet里配置拦截此请求。

以下是解决步骤:

首先,修改 WebSocketConfig 类定义,在类上添加 @Configuration 注解,表明该类以 JavaConfig 形式用作 bean 定义的源(相当于 XML 配置中的 元素)。

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.config.annotation.EnableWebSocket;

import org.springframework.web.socket.config.annotation.WebSocketConfigurer;

import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration

@EnableWebSocket

public class WebSocketConfig implements WebSocketConfigurer {

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {

registry.addHandler(marcoHandler(), "/marco");

}

@Bean

public MarcoHandler marcoHandler() {

return new MarcoHandler();

}

}

其次,使用 JavaConfig 配置 DispatcherServlet,继承org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer ,重载以下 3 个方法:

- getRootConfigClasses – 返回带有 @Configuration 注解的类将会用来配置 ContextLoaderListener 创建的应用上下文中的 bean

- getServletConfigClasses – 返回带有 @Configuration 注解的类将会用来定义 DispatcherServlet 应用上下文中的 bean

- getServletMappings – 将一个或多个路径映射到 DispatcherServlet 上

实际上,如果只需要 Spring WebSocket 生效,则只需要在 getServletConfigClasses 方法中返回用来定义 DispatcherServlet 应用上下文中的 bean

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class WebSocketInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

@Override

protected Class>[] getRootConfigClasses() {

return null;

}

@Override

protected Class>[] getServletConfigClasses() {

return new Class>[] {WebSocketConfig.class};

}

@Override

protected String[] getServletMappings() {

return new String[] {"/"};

}

}

重新部署后代开浏览器运行成功

客户端消息

2fdc9460aab198c07450863078afba86.png

服务器消息

aee5a488a10afda9acce5a2d0c813292.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

要在Spring MVC中整合WebSocket并获取请求参数,可以按照以下步骤进行: 1. 添加Maven依赖 ```xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.2.3.RELEASE</version> </dependency> ``` 2. 配置WebSocketSpring MVC的配置类中添加WebSocket配置: ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/websocket").setAllowedOrigins("*"); } @Bean public WebSocketHandler myHandler() { return new MyHandler(); } } ``` 其中,`MyHandler`是自定义的WebSocket处理器。 3. 实现WebSocket处理器 实现`WebSocketHandler`接口,并在`afterConnectionEstablished`方法中获取请求参数: ```java public class MyHandler implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { Map<String, String> queryParams = getQueryParams(session); // 处理WebSocket连接建立后的逻辑 } private Map<String, String> getQueryParams(WebSocketSession session) { URI uri = session.getUri(); String query = uri.getQuery(); return parseQuery(query); } private Map<String, String> parseQuery(String query) { Map<String, String> queryParams = new HashMap<>(); if (query != null) { String[] parts = query.split("&"); for (String part : parts) { String[] keyValue = part.split("="); if (keyValue.length == 2) { String key = keyValue[0]; String value = keyValue[1]; queryParams.put(key, value); } } } return queryParams; } // 其他WebSocketHandler接口的实现 // ... } ``` 在`getQueryParams`方法中,通过`WebSocketSession`对象的`getUri`方法获取请求的URI,再通过`parseQuery`方法解析出参数。 4. 客户端发送请求 在客户端使用WebSocket发送请求时,可以在URL后面添加参数: ```javascript var socket = new WebSocket("ws://localhost:8080/websocket?param1=value1&param2=value2"); ``` 这样,在WebSocket连接建立后,`MyHandler`中的`afterConnectionEstablished`方法就能够获取到这些参数了。 以上就是在Spring MVC中整合WebSocket并获取请求参数的方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值