Spring websocket浏览器连接时出现404错误

1、场景

在用websocket做一个简单的数据导入页面同步显示后台进度功能的时候,浏览器出现连接不上的错误:
WebSocket connection to 'ws://localhost:8080/project/marco' failed: Error during WebSocket handshake: Unexpected response code: 404

网上有很种导致404的情况,但是都没有用,我在这里记录一下我的情况。

2、解决过程

spring-websocket.xml的配置:

<websocket:handlers>
<websocket:mapping handler="messageHandler" path="/marco" />
<websocket:handshake-interceptors>
  <bean class="com.project.websocket.HandshakeInterceptor"/>
</websocket:handshake-interceptors>
</websocket:handlers>

<bean id="messageHandler" class="com.project.websocket.MessageHandler"/>

查看打印的INFO级别日志,根据spring的启动信息我们可以看到:

2017-02-09 21:57:40,559 INFO  [springframework.web.servlet.handler.SimpleUrlHandlerMapping] - Mapped URL path [/marco] onto handler of type [class org.springframework.web.socket.server.support.WebSocketHttpRequestHandler]

WebSocketHttpRequestHandler通过SimpleUrlHandlerMapping注册了/marco地址,那应该是没错的啊,难道是客户端js的错误?

var websocket = new WebSocket('ws://' + window.location.host + '/project/marco');

地址好像也没错啊,和Spring in Action4里面的例子一样的啊。
为什么地址没有映射到/marco?先看看DispatchServlet的handlerMappings有没有/marco先吧。

断点DispatchServlet的doDispatch()方法,随便发起一个请求:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ......
    // Determine handler for the current request.
    mappedHandler = getHandler(processedRequest);
    if (mappedHandler == null || mappedHandler.getHandler() == null) {
        noHandlerFound(processedRequest, response);
        return;
    }
    ......
}

进入getHandler(processedRequest)

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    for (HandlerMapping hm : this.handlerMappings) {
        if (logger.isTraceEnabled()) {
            logger.trace(
                    "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
        }
        HandlerExecutionChain handler = hm.getHandler(request);
        if (handler != null) {
            return handler;
        }
    }
    return null;
}

我们看一下handlerMappings里面的内容,不知道你们有没有找到/marco,反正我是没找到。
言下之意,/marco没注册到?

没办法,我们断点SimpleUrlHandlerMapping的registerHandlers()方法和DispatchServlet的initHandlerMappings()方法。

我们看到SimpleUrlHandlerMapping的registerHandlers()先被执行。

最后退出registerHandlers()方法,F6一路下来,从WebApplicationObjectSupport的initApplicationContext()方法中可以看到:

  • context.beanFactory.beanDefintionMap中包含[org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0->RootBeanDefintion]
  • 而且context.beanFactory.singletonObjects也包含了注册了/marco的SimpleUrlHandlerMapping实例。
  • 此时的context.configLocations是classpath:spring-context.xml

DispatchServlet的initHandlerMappings()后被执行,我们来看这段:

// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map<String, HandlerMapping> matchingBeans =
    BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);

然而,在matchingBeans没有找到我们要的注册了/marco的SimpleUrlHandlerMapping。此时的context.configLocations是classpath*:spring-servlet.xml

来到这里,你大概知道就是你的spring-websocket.xml放错位置啦。

3、解决办法

如果你的web.xml分开加载spring-context和spring-servlet的话,请将spring-websocket的资源文件放到spring-servlet上加载。
注意:在spring-context加载的时候,你的messageHandler应该是还没有初始化,请不要注入到某个service上。

转载于:https://www.cnblogs.com/ginponson/p/6390975.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值