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

嵌入式Tomcat 8.5.95中ServerContainer为空,WebSocket无法使用

解决嵌入式Tomcat 8.5获取ServerContainer为null的问题

核心原因

嵌入式Tomcat默认不会自动注册WebSocket相关的初始化器(WsSci),导致ServletContext中无法通过javax.websocket.server.ServerContainer属性获取到实例,必须手动触发WebSocket容器的初始化流程。

解决方案

方法1:手动注册Tomcat的WebSocket初始化器WsSci

在创建Tomcat上下文后,手动添加org.apache.tomcat.websocket.server.WsSci作为ServletContainerInitializer,这个类会负责初始化ServerContainer并将其绑定到ServletContext中。

修改你的main方法:

public static void main(String[] args) throws Exception {
    Tomcat tomcat = new Tomcat();
    tomcat.setPort(8080);
    
    // 保持你原有上下文配置
    var ctx = tomcat.addWebapp("", new File(".").getAbsolutePath());
    
    // 关键步骤:添加Tomcat自带的WebSocket初始化器WsSci
    ctx.addServletContainerInitializer(new org.apache.tomcat.websocket.server.WsSci(), null);
    // 再添加自定义初始化器
    ctx.addServletContainerInitializer(new Init(), null);
    
    // 原有HTTP Servlet配置
    Tomcat.addServlet(ctx, "tunnel", new DummyGuacamoleTunnelServlet()); 
    ctx.addServletMappingDecoded("/tunnel", "tunnel");
    
    tomcat.start();
    tomcat.getServer().await();
}

方法2:直接通过Tomcat API获取并初始化ServerContainer

如果方法1不生效,可以绕过ServletContext的自动绑定逻辑,手动创建并绑定WebSocket容器实例:

// 在main方法中、tomcat.start()之前执行
org.apache.tomcat.websocket.server.WsServerContainer container = 
    (org.apache.tomcat.websocket.server.WsServerContainer) ctx.getServletContext().getAttribute(
        org.apache.tomcat.websocket.server.WsServerContainer.class.getName()
    );

// 若容器未初始化,则手动创建并绑定
if (container == null) {
    container = new org.apache.tomcat.websocket.server.WsServerContainer(ctx.getServletContext());
    ctx.getServletContext().setAttribute(
        javax.websocket.server.ServerContainer.class.getName(),
        container
    );
}

// 注册你的WebSocket端点
ServerEndpointConfig config = ServerEndpointConfig.Builder.create(
        DummyGuacamoleWebsocketEndpoint.class, "/websocket-tunnel")
        .subprotocols(Arrays.asList("guacamole"))
        .build();
container.addEndpoint(config);

依赖优化

移除重复的WebSocket API依赖,确保版本一致性:

dependencies {
    implementation("org.apache.guacamole:guacamole-common:1.5.3")
    implementation("org.apache.tomcat.embed:tomcat-embed-core:8.5.95")
    implementation("org.apache.tomcat.embed:tomcat-embed-websocket:8.5.95")
    compileOnly("javax.websocket:javax.websocket-api:1.1")
}

验证修改

完成上述调整后启动应用,Init类中的ServerContainer将能正常获取实例,WebSocket端点可成功注册并工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:04:54