Spring 5 WebSocket端点无法访问(Tomcat部署),请求排查原因
针对你遇到的Tomcat部署Spring应用中WebSocket端点无法访问(返回404)的问题,结合你的配置环境,可能的原因及解决方法如下:
WebSocket命名空间未正确引入
检查Spring应用上下文XML的头部,必须包含websocket命名空间及对应的schema定义,否则<websocket:handlers>配置不会被Spring解析,映射规则无法生效。正确的XML头部示例:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">DispatcherServlet未覆盖WebSocket请求路径
确认web.xml中DispatcherServlet的映射规则是否包含WebSocket端点路径。如果DispatcherServlet仅映射特定后缀(如*.json)或子路径(如/api/*),/events请求会绕过Spring直接被Tomcat拒绝。建议将DispatcherServlet映射设置为/,确保所有请求(包括WebSocket)都能被Spring处理:<servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>缺少Spring WebSocket核心依赖
确保项目依赖中包含spring-websocket库(版本需与Spring其他组件一致)。比如Maven依赖配置:<dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency>缺少该依赖时,Spring无法初始化WebSocket相关的处理器映射和适配器,即使
MyWebSocketHandler被加载,也无法处理请求。Tomcat WebSocket API冲突
如果项目手动引入了javax.websocket-api或jakarta.websocket-api依赖,需将其作用域设为provided——Tomcat自带WebSocket API实现,重复依赖会导致类加载冲突,进而无法完成握手:<dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency>未配置握手处理器
显式配置DefaultHandshakeHandler,确保Spring能处理HTTP到WebSocket的升级请求。修改WebSocket配置如下:<bean id="handshakeHandler" class="org.springframework.web.socket.server.support.DefaultHandshakeHandler"/> <websocket:handlers> <websocket:mapping handler="myWebSocketHandler" path="/events"/> <websocket:handshake-handler ref="handshakeHandler"/> </websocket:handlers>路径匹配拦截或冲突
检查应用中是否存在Spring Security拦截器、自定义Filter等组件阻止了/events路径的请求。可临时关闭拦截器测试,或在拦截配置中明确放行WebSocket端点路径。
内容的提问来源于stack exchange,提问作者Johnson

