JSR-356 (Java Specification Request 356)是 Java 平台中关于 WebSocket 编程的标准 API 规范,全称为:
Java™ API for WebSocket
(Java WebSocket API)
它于 2013 年作为 Java EE 7 的核心组成部分正式发布 ,旨在为 Java 开发者提供一套标准、可移植、易用的 WebSocket 编程接口,用于构建实时、双向、全双工的 Web 通信应用。
一、背景与动机
在 WebSocket 出现前,Web 应用依赖 HTTP 的"请求-响应"模型,无法实现服务器主动推送数据。开发者常使用"轮询"或"长轮询"等 hack 方式模拟实时通信,效率低下。
- 2011 年 :IETF 发布 WebSocket 协议标准 RFC 6455
- 2013 年:JSR-356 跟进,为 Java 提供官方 WebSocket API
- 目标:避免各厂商(如 Tomcat、Jetty)自定义 API 导致的碎片化,实现"一次编写,到处运行"
二、核心目标
- ✅ 标准化 WebSocket 编程模型
- 统一服务器端和 Java 客户端的 API
- ✅ 支持两种编程风格
- 注解驱动(Annotation-driven)
- 接口驱动(Programmatic/Endpoint-based)
- ✅ 与 Java EE 容器无缝集成
- 支持 CDI、EJB、安全、事务等企业特性
- ✅ 轻量、高效、低延迟
- 利用 WebSocket 全双工、无头部开销的优势
三、主要特性与 API
1. 两种端点(Endpoint)创建方式
| 类型 | 说明 | 示例 |
|---|---|---|
| 注解式端点 | 使用 @ServerEndpoint 装饰 POJO |
简洁,适合简单场景 |
| 编程式端点 | 继承 javax.websocket.Endpoint |
灵活,适合复杂生命周期控制 |
示例:注解式 WebSocket 服务端
java
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/chat")
public class ChatServer {
@OnOpen
public void onOpen(Session session) {
System.out.println("连接建立: " + session.getId());
}
@OnMessage
public void onMessage(String message, Session session) {
// 广播消息
session.getBasicRemote().sendText("Echo: " + message);
}
@OnClose
public void onClose(Session session) {
System.out.println("连接关闭");
}
@OnError
public void onError(Throwable error) {
error.printStackTrace();
}
}
2. 关键组件
| 类/注解 | 作用 |
|---|---|
@ServerEndpoint |
声明 WebSocket 服务端点路径 |
Session |
表示一个 WebSocket 连接会话,用于发送消息、获取属性等 |
@OnOpen, @OnMessage, @OnClose, @OnError |
生命周期回调方法 |
RemoteEndpoint |
用于向对端发送文本或二进制消息(BasicRemote / AsyncRemote) |
ClientManager / ContainerProvider |
用于创建 Java WebSocket 客户端 |
3. 客户端支持
JSR-356 不仅定义服务端 API,也包含 Java 客户端 API:
java
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(MyClient.class, URI.create("ws://localhost:8080/chat"));
四、与 Servlet 和 JSR-340 的关系
- JSR-340(Servlet 3.1) 提供了底层的 HTTP 协议升级机制 (
upgrade()方法) - JSR-356 在此基础上构建完整的 WebSocket 协议栈
- 实际部署时,WebSocket 握手通过 HTTP Upgrade 完成,之后切换到 WebSocket 帧传输
🔗 两者协同工作:Servlet 处理握手,WebSocket API 处理后续通信。
五、支持的容器
所有 Java EE 7 及以上 或 Jakarta EE 8+ 兼容的应用服务器均支持 JSR-356,包括:
- WildFly / JBoss EAP
- WebLogic 12c+
- WebSphere Liberty
- GlassFish 4+
- Tomcat 7.0.47+ / 8+
- Jetty 9.1+
💡 即使在 Spring Boot 中使用内嵌 Tomcat/Jetty,底层仍依赖 JSR-356 实现。
六、与 Spring WebSocket 的关系
- Spring WebSocket 是对 JSR-356 的封装和增强(如支持 SockJS 降级、STOMP 协议)
- Spring 默认使用 JSR-356 作为底层 WebSocket 实现
- 若需直接使用标准 API(不依赖 Spring),可直接编写
@ServerEndpoint类
七、总结
| 项目 | 内容 |
|---|---|
| JSR 编号 | 356 |
| 规范名称 | Java API for WebSocket |
| 所属平台 | Java EE 7 / Jakarta EE 8+ |
| 核心价值 | 提供标准、可移植的 WebSocket 编程接口 |
| 关键能力 | 实时双向通信、低延迟、全双工、跨平台 |
| 典型应用 | 聊天室、实时仪表盘、在线游戏、协作编辑 |
🌐 有了 JSR-356,Java 开发者终于可以用统一的方式构建现代实时 Web 应用,告别 vendor lock-in。
官方文档(Jakarta EE 版本):
https://jakarta.ee/specifications/websocket/