Spring Boot 3.4.7整合WebFlux启动报错NoClassDefFoundError: jakarta/servlet/ServletException求助
Spring Boot 3.4.7整合WebFlux启动报错NoClassDefFoundError: jakarta/servlet/ServletException求助
嗨,我来帮你捋捋这个启动报错的问题~
你遇到的NoClassDefFoundError: jakarta/servlet/ServletException,核心原因是混用了Spring MVC(Servlet栈)和WebFlux(响应式栈)的注解:
- 你已经排除了Tomcat(Servlet容器),改用Netty来跑WebFlux的响应式服务,但你的全局异常处理器用了
@RestControllerAdvice——这个注解是Spring MVC专属的,底层依赖Servlet相关的类,所以启动时找不到对应的Servlet类就报错了。
给你两个可行的解决方案,按需选择:
方案1:修改异常处理器适配WebFlux
把@RestControllerAdvice替换成通用的@ControllerAdvice,同时把返回值改成WebFlux支持的响应式类型(比如Mono<String>),这样就能和WebFlux的异步非阻塞模型匹配:
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import reactor.core.publisher.Mono; import org.springframework.http.HttpStatus; @ControllerAdvice public class GlobalRestControllerExceptionHandler { @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler(Exception.class) public Mono<String> handleException(Exception e) { System.out.println(e.getMessage()); return Mono.just("There was my error"); } }
方案2:使用WebFlux专属的错误处理机制(更推荐)
WebFlux有自己的错误处理接口ErrorWebExceptionHandler,实现它可以更灵活地处理响应式场景下的异常:
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import org.springframework.core.io.buffer.DataBuffer; import java.nio.charset.StandardCharsets; @Component public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler { @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { ServerHttpResponse response = exchange.getResponse(); // 设置响应状态码 response.setStatusCode(HttpStatus.BAD_REQUEST); // 打印异常信息 System.out.println(ex.getMessage()); // 构造响应内容 String errorMessage = "There was my error"; DataBuffer buffer = response.bufferFactory().wrap(errorMessage.getBytes(StandardCharsets.UTF_8)); // 返回响应 return response.writeWith(Mono.just(buffer)); } }
额外注意事项
- 检查你的依赖:确保只引入了
spring-boot-starter-webflux,不要同时引入spring-boot-starter-web(哪怕排除了Tomcat,也可能带来不必要的Servlet依赖)。你的pom.xml应该类似这样:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- 移除spring-boot-starter-web的依赖,避免混淆栈 -->
这样修改后,你的应用应该能正常启动,而且访问无效URL时也能触发全局异常处理,返回你定义的错误信息啦~
内容来源于stack exchange
相关产品推荐
相关产品推荐

