You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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来实现。

步骤如下:

  1. 引入Jetty WebSocket依赖(Maven示例):
<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-websocket</artifactId>
    <version>8.1.16.v20140903</version> <!-- 选兼容Spring3的稳定版本 -->
    <scope>provided</scope> <!-- 容器本身通常自带该依赖,避免冲突 -->
</dependency>
  1. 实现自定义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) {
        // 连接关闭时的资源清理逻辑
    }
}
  1. 在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集成。

步骤如下:

  1. 引入Tomcat WebSocket依赖:
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat7-websocket</artifactId>
    <version>7.0.96</version>
    <scope>provided</scope>
</dependency>
  1. 实现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 {
        // 二进制消息处理(按需实现)
    }
}
  1. 注册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集成非常友好。

步骤如下:

  1. 引入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>
  1. 实现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() {
        // 资源销毁逻辑
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:28:09