Spring 3是否支持WebSocket?遗留Spring 3项目如何实现?
在Spring 3中实现WebSocket的可行方案
哥们,先给你拍板定案:Spring 3本身并没有原生支持WebSocket——毕竟Spring3在2009年就发布了,WebSocket直到2011年才被引入,时间线对不上嘛。不过别慌,咱们可以通过第三方库或者容器自带的WebSocket API来实现实时通信,下面给你拆解几个可行的方案:
方案一:集成Jetty容器的WebSocket API
Jetty是最早支持WebSocket的Servlet容器之一,只要你的Spring3应用部署在Jetty 7.6+或Jetty 8+上,就能用它的原生WebSocket API来实现。
步骤如下:
- 引入Jetty WebSocket依赖(Maven示例):
<dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-websocket</artifactId> <version>8.1.16.v20140903</version> <!-- 选兼容Spring3的稳定版本 --> <scope>provided</scope> <!-- 容器本身通常自带该依赖,避免冲突 --> </dependency>
- 实现自定义WebSocket处理器:
import org.eclipse.jetty.websocket.WebSocket; import java.io.IOException; public class MyJettyWebSocket implements WebSocket.OnTextMessage { private Connection connection; @Override public void onOpen(Connection connection) { this.connection = connection; // 这里可以通过Spring上下文获取需要的Bean,比如: // MyService service = ApplicationContextHolder.getBean(MyService.class); } @Override public void onMessage(String data) throws IOException { // 处理客户端发来的消息 System.out.println("收到WebSocket消息:" + data); connection.sendMessage("已收到你的消息:" + data); } @Override public void onClose(int closeCode, String message) { // 连接关闭时的资源清理逻辑 } }
- 在Spring中注册WebSocket Servlet:
如果用Spring 3.1+的嵌入式Jetty容器,可通过配置类注册:
import org.eclipse.jetty.websocket.WebSocketServlet; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.ServletRegistrationBean; @Configuration @EnableWebMvc public class WebConfig { @Bean public JettyEmbeddedServletContainerFactory jettyContainer() { JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(8080); // 注册WebSocket处理器的Servlet factory.addServletRegistrations(new ServletRegistrationBean(new WebSocketServlet() { @Override public WebSocket doWebSocketConnect(javax.servlet.http.HttpServletRequest request, String protocol) { return new MyJettyWebSocket(); } }, "/ws/*")); return factory; } }
方案二:集成Tomcat的WebSocket API
如果你的应用部署在Tomcat 7.0.27+或Tomcat 8上,Tomcat已经自带了WebSocket实现,同样可以和Spring3集成。
步骤如下:
- 引入Tomcat WebSocket依赖:
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat7-websocket</artifactId> <version>7.0.96</version> <scope>provided</scope> </dependency>
- 实现Tomcat风格的WebSocket Endpoint:
import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.WsOutbound; import java.io.IOException; import java.nio.CharBuffer; public class MyTomcatWebSocket extends MessageInbound { @Override protected void onOpen(WsOutbound outbound) { // 连接建立时的初始化逻辑 } @Override protected void onTextMessage(CharBuffer message) throws IOException { String msg = message.toString(); System.out.println("收到Tomcat WebSocket消息:" + msg); getWsOutbound().writeTextMessage(CharBuffer.wrap("Tomcat回复:" + msg)); } @Override protected void onClose(int status) { // 连接关闭时的清理逻辑 } @Override protected void onBinaryMessage(java.nio.ByteBuffer message) throws IOException { // 二进制消息处理(按需实现) } }
- 注册WebSocket Servlet:
import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import javax.servlet.annotation.WebServlet; @WebServlet("/tomcat-ws/*") public class MyWebSocketServlet extends WebSocketServlet { @Override protected StreamInbound createWebSocketInbound(String subProtocol, javax.servlet.http.HttpServletRequest request) { return new MyTomcatWebSocket(); } }
最后在Spring的web.xml或配置类中注册这个Servlet即可。
方案三:使用Atmosphere框架做跨容器兼容
Atmosphere是一个专注于实时通信的框架,支持WebSocket、Comet等多种协议,还能自动适配不同容器的实现,和Spring3集成非常友好。
步骤如下:
- 引入Atmosphere依赖:
<dependency> <groupId>org.atmosphere</groupId> <artifactId>atmosphere-runtime</artifactId> <version>2.4.21</version> <!-- 选兼容Spring3的稳定版本 --> </dependency> <dependency> <groupId>org.atmosphere</groupId> <artifactId>atmosphere-spring</artifactId> <version>2.4.21</version> </dependency>
- 实现Atmosphere Handler:
import org.atmosphere.cpr.AtmosphereResource; import org.atmosphere.cpr.AtmosphereResourceEvent; import org.atmosphere.cpr.AtmosphereResourceEventListenerAdapter; import org.atmosphere.handler.AbstractReflectorAtmosphereHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class MyAtmosphereHandler extends AbstractReflectorAtmosphereHandler { @Override public void onRequest(AtmosphereResource resource) throws IOException { HttpServletRequest request = resource.getRequest(); // 针对WebSocket连接做处理 if (resource.transport().equals(AtmosphereResource.TRANSPORT.WEBSOCKET)) { resource.addEventListener(new AtmosphereResourceEventListenerAdapter() { @Override public void onMessage(AtmosphereResourceEvent event) { if (event.getMessage() != null) { String msg = event.getMessage().toString(); System.out.println("收到Atmosphere消息:" + msg); try { resource.getResponse().getWriter().write("Atmosphere回复:" + msg); } catch (IOException e) { e.printStackTrace(); } } } }); } } @Override public void destroy() { // 资源销毁逻辑 } }
- 在Spring中配置Atmosphere Servlet:
在web.xml中添加如下配置:
<servlet> <servlet-name>AtmosphereServlet</servlet-name> <servlet-class>org.atmosphere.cpr.AtmosphereServlet</servlet-class> <init-param> <param-name>org.atmosphere.cpr.AtmosphereHandler</param-name> <param-value>com.example.MyAtmosphereHandler</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>AtmosphereServlet</servlet-name> <url-pattern>/atmosphere-ws/*</url-pattern> </servlet-mapping>
关键注意事项
- 这些方案都属于非原生Spring支持,所以需要手动处理WebSocket和Spring Bean的集成(比如通过ApplicationContext上下文获取Bean)。
- 务必注意容器版本兼容性:比如Jetty 8+、Tomcat 7.0.27+才能稳定支持WebSocket。
- 如果后续有升级到Spring4的计划,迁移到Spring原生WebSocket模块会更省心,但目前遗留系统用这些方案完全能满足需求。
内容的提问来源于stack exchange,提问作者Mehraj Malik
相关产品推荐
相关产品推荐

