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

Spring+Jetty实现基础WebSocket遇空指针异常求助

解决方案

1. 核心问题分析

空指针的根源是JettyWebSocketServerContainer未被正确初始化并注入到JettyRequestUpgradeStrategy中。你手动实例化了JettyRequestUpgradeStrategy,但该实例无法关联到Jetty服务器的WebSocket容器上下文,导致升级时容器对象为null。

2. 修正配置:使用Jetty服务器Customizer绑定容器

无需手动创建JettyRequestUpgradeStrategy,通过WebServerFactoryCustomizer配置Jetty的WebSocket容器,让Spring自动管理升级策略:

修改后的WebSocket配置类:

import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
import java.time.Duration;

@Configuration
@EnableWebSocket
public class MyWebSocketConfig implements WebSocketConfigurer {

    private final MyWebSocketHandler myWebSocketHandler;

    // 构造注入替代@Autowired,符合Spring最佳实践
    public MyWebSocketConfig(MyWebSocketHandler myWebSocketHandler) {
        this.myWebSocketHandler = myWebSocketHandler;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry
                .addHandler(myWebSocketHandler, "/init")
                .setHandshakeHandler(defaultHandshakeHandler())
                .setAllowedOrigins("*");
    }

    @Bean
    public DefaultHandshakeHandler defaultHandshakeHandler() {
        // Spring会自动注入适配Jetty的升级策略实例
        return new DefaultHandshakeHandler();
    }

    @Bean
    public WebServerFactoryCustomizer<JettyServletWebServerFactory> jettyWebSocketCustomizer() {
        return factory -> {
            factory.addServerCustomizers(server -> {
                // 初始化Jetty WebSocket容器并绑定到服务器上下文
                var containerInitializer = org.eclipse.jetty.ee10.websocket.server.WebSocketServerContainerInitializer.configureContext(server.getContext());
                // 配置WebSocket参数
                containerInitializer.setInputBufferSize(8192);
                containerInitializer.setIdleTimeout(Duration.ofSeconds(600));
            });
        };
    }
}

3. 依赖优化:移除冗余组件

Spring Boot Starter已包含所有必要的Spring核心依赖,删除单独引入的spring-web、spring-orm等,避免版本冲突:

简化后的Gradle依赖:

// Spring Boot Starter 核心依赖
implementation 'org.springframework.boot:spring-boot-starter-web:3.3.7'
implementation("org.springframework.boot:spring-boot-starter-jetty:3.3.7") {
    exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
}
implementation 'org.springframework.boot:spring-boot-starter-data-jpa:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-cache:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-log4j2:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-websocket:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-security:3.3.7'
implementation 'org.springframework.boot:spring-boot-starter-actuator:3.3.7'

// 仅保留Starter未覆盖的业务依赖(如需要特定版本的Spring Data JPA)
// implementation 'org.springframework.data:spring-data-jpa:3.3.3'

4. 关键注意事项

  • 不要手动实例化JettyRequestUpgradeStrategy:Spring Boot会根据当前Web服务器自动配置对应的升级策略,并注入正确的容器对象。
  • 使用WebServerFactoryCustomizer是Jetty EE10的标准配置方式:确保WebSocket容器与Jetty服务器上下文正确绑定。
  • 清理冗余依赖:减少版本冲突和类加载问题的概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:14:56