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
按照 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 错误
上网搜索了一晚上解决方案,包括参考 *.com 上的经验都未解决该问题,直到查看到以下文章:
spring集成websocket页面访问404问题的解决方法
在此自己也做个记录避免以后遗忘。
websocket 实质上借用 http 请求进行握手,启用 spring websocket 需要在 org.springframework.web.servlet.dispatcherservlet 里配置拦截此请求。
以下是解决步骤:
首先,修改 websocketconfig 类定义,在类上添加 @configuration 注解,表明该类以 javaconfig 形式用作 bean 定义的源(相当于 xml 配置中的 <beans> 元素)。
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[] {"/"}; } }
重新部署后代开浏览器运行成功
客户端消息
服务器消息
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Spring集成webSocket页面访问404问题的解决方法
-
WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法
-
Spring MVC参数自动绑定List的解决方法
-
SQL Server 完整备份遇到的一个不常见的错误及解决方法
-
Spring MVC 404 Not Found无错误日志的解决方法
-
SpringBoot配置SwaggerUI访问404错误的解决方法
-
linux下mysql提示"mysql deamon failed to start"错误的解决方法
-
asp.net 错误:0x8007000B 异常的解决方法
-
关于javaWeb中405错误的解决方法
-
微信js sdk invalid signature签名错误问题的解决方法分析