06-Spring MVC使用WebSocket遇到的404问题

使用配置文件声明如下


    <websocket:handlers>
        <websocket:mapping path="/hello" handler="helloHandler"/>
    websocket:handlers>

    <bean id="helloHandler" class="cn.sysuygm.web.MyWebSocketHandler"/>

服务端

public class MyWebSocketHandler extends AbstractWebSocketHandler {

//    重写文本类型的消息处理器
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {

//        1. 收到消息,从消息中取出下层交付上来的内容
        System.out.println("收到消息"+ message.getPayload());

//        2. 延时
        Thread.sleep(2000);

//        3. 发送文本消息给客户端
        System.out.println("发送消息: Hello world!");
        session.sendMessage(new TextMessage("hello world"));
    }

//    连接建立时的处理器
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
//        super.afterConnectionEstablished(session);
        System.out.println("建立连接");
    }

//    ;连接关闭时的处理器
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
//        super.afterConnectionClosed(session, status);
        System.out.println("关闭连接");
    }

}

客户端

<%--
  Created by IntelliJ IDEA.
  User: jiamoufang
  Date: 2019/1/7
  Time: 17:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
    <title>websocket测试title>
    <script type="text/javascript">

        var url = 'ws://' +window.location.host + '<%=request.getContextPath()%>/hello';
        var sock = new WebSocket(url);

        sock.onopen = function() {
            console.log('开启WebSocket连接!');
            sayHello();
        }

        sock.onmessage = function(e) {
            console.log('接受消息: ', e.data);
            setTimeout(function(){sayHello()}, 2000);
        }

        sock.onclose = function() {
            console.log('关闭WebSocket连接!');
        }

        function sayHello() {
            console.log('发送消息: hello world!')
            sock.send('hello world....');
        }
    script>
head>
<body>
发送页面
body>
html>

完成以上之后启动服务器,浏览器访问 http://localhost:8080/chapter17/hello.jsp , 结果出现404.

查阅相关说法如下:

var url = 'ws://' +window.location.host + '<%=request.getContextPath()%>/hello';
        var sock = new WebSocket(url);

发起WebSocket连接请求也是一个HTTP请求,会被DispatcherServlet拦截,按照一般的处理流程,DispatcherServlet会去查映射路径对应的处理方法,但是MyWebSocketHandler并没有出现在处理方法中。

解决方法

手动添加以下到web处理器类的相同类包下。

//开启websocket
@EnableWebSocket
public class MyWebSocketConfig implements WebSocketConfigurer {


//    关键一步
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
        webSocketHandlerRegistry.addHandler(helloHandler(),"/hello");
    }

    @Bean
    public MyWebSocketHandler helloHandler(){
        return new MyWebSocketHandler();
    }
}

告诉DispatcherServlet遇到注解@EnableWebSocket时获取MyWebSocketConfig配置类,从而使得配置生效。这样才能将属于WebSocket的请求路径告知于DispatcherServlet,DispatcherServlet才能做出相应的处理。

// 有可能跟Spring版本相关,必须继承 AbstractAnnotationConfigDispatcherServletInitializer
// 且让 getServletConfigClasses 返回 自定义的WebSocket配置类 MyWebSocketConfig
public class WebSocketInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {MyWebSocketConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

你可能感兴趣的:(Spring)