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

Jetty 10迁移至Jetty 12:WebSocketServerComponents用法适配问题

Jetty 12(EE8)WebSocket迁移适配方案

针对你从Jetty 10(EE8)迁移到Jetty 12(EE8)时遇到的WebSocketServerComponents.ensureWebSocketComponents()用法问题,核心原因是Jetty 12对架构做了重大拆分——将EE规范实现(Servlet、WebSocket等)与Jetty核心服务器逻辑完全隔离,导致原有的Context API和组件初始化方式发生了变化,以下是具体的适配方案:

关键变化说明

  1. Context类迁移:原org.eclipse.jetty.server.handler.ContextHandler.Context已迁移至EE8模块下的org.eclipse.jetty.ee8.nested.ContextHandler.APIContext,且不再暴露getServer()方法,这是为了隔离EE层与Jetty核心层的依赖,避免直接操作核心服务器对象。
  2. WebSocket组件包迁移:所有EE8相关的WebSocket类从org.eclipse.jetty.websocket.server/servlet包迁移至org.eclipse.jetty.websocket.ee8.server/servlet包,必须调整导入路径才能兼容。

适配方案

1. 调整导入包

将原WebSocket相关导入替换为EE8模块下的类:

// 替换前
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
import org.eclipse.jetty.websocket.server.JettyWebSocketServlet;
import org.eclipse.jetty.websocket.server.JettyWebSocketServletFactory;
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;

// 替换后
import org.eclipse.jetty.ee8.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.ee8.server.JettyWebSocketCreator;
import org.eclipse.jetty.websocket.ee8.server.JettyWebSocketServerContainer;
import org.eclipse.jetty.websocket.ee8.server.JettyWebSocketServlet;
import org.eclipse.jetty.websocket.ee8.server.JettyWebSocketServletFactory;
import org.eclipse.jetty.websocket.ee8.servlet.WebSocketUpgradeFilter;

2. 修改WebSocket组件初始化逻辑

Jetty 12的WebSocketServerComponents提供了重载方法,无需传入Server对象,直接使用ServletContext即可完成组件初始化。同时JettyWebSocketServerContainer.ensureContainer()会自动触发依赖组件的初始化,可简化代码:

@Override
public void init() throws ServletException {
    final ServletContext osgiServletContext = super.getServletContext().getContext("/");
    context = ServletContextHandler.getServletContextHandler(osgiServletContext, "WebSockets");

    JettyWebSocketServerContainer serverContainer = JettyWebSocketServerContainer.getContainer(osgiServletContext);
    if (serverContainer == null) {
        // 无需传入Server,直接用ServletContext初始化核心组件
        WebSocketServerComponents.ensureWebSocketComponents(osgiServletContext);
        WebSocketUpgradeFilter.ensureFilter(osgiServletContext);
        WebSocketMappings.ensureMappings(osgiServletContext);
        // 自动创建并初始化WebSocket容器
        serverContainer = JettyWebSocketServerContainer.ensureContainer(osgiServletContext);
    }
    super.init();
}

最佳实践建议

虽然在Servlet的init()方法中初始化WebSocket组件仍然可行,但更符合Jetty 12架构设计的方式是:

  • 在ServletContextListener中完成WebSocket组件的初始化,避免在Servlet内部直接操作容器级组件;
  • 若使用Jetty的程序化配置(而非OSGi声明式),可在Server启动阶段通过ServletContextHandler直接配置WebSocket组件,例如:
    ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    // 配置WebSocket容器
    JettyWebSocketServerContainer container = JettyWebSocketServerContainer.ensureContainer(contextHandler.getServletContext());
    container.addEndpoint(MyWebSocketEndpoint.class);
    

注意事项

  • 确保OSGi环境中已正确安装并激活Jetty的jetty-ee8-websocket-server、jetty-ee8-servlet等模块;
  • 避免尝试通过反射或其他方式获取Jetty核心Server对象,这会破坏EE层与核心层的隔离设计,导致后续版本兼容性问题。

内容的提问来源于stack exchange,提问作者langri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 11:45:16