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
相关产品推荐
相关产品推荐

