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

Spring Boot Web依赖Tomcat引发NoSuchMethodError及替换方案问询

问题描述

在使用Spring Boot 2.7.15版本时,同时引入spring-boot-starter-web和spring-boot-starter-webflux依赖后,出现NoSuchMethodError错误,具体错误日志如下:

2023-09-11T10:48:54,424 INFO  [http-nio-8082-exec-1] log: Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-09-11T10:48:54,425 INFO  [http-nio-8082-exec-1] initServletBean: Initializing Servlet 'dispatcherServlet'
2023-09-11T10:48:54,425 INFO  [http-nio-8082-exec-1] initServletBean: Completed initialization in 0 ms
2023-09-11T10:48:54,453 ERROR [http-nio-8082-exec-2] log: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getHttpServletMapping()Ljavax/servlet/http/HttpServletMapping;
    at org.apache.catalina.core.ApplicationHttpRequest.setRequest(ApplicationHttpRequest.java:681)
    at org.apache.catalina.core.ApplicationHttpRequest.<init>(ApplicationHttpRequest.java:103)
    at org.apache.catalina.core.ApplicationDispatcher.wrapRequest(ApplicationDispatcher.java:857)
    at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:570)
    at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:558)
    at org.apache.catalina.core.AsyncContextImpl$AsyncRunnable.run(AsyncContextImpl.java:563)
    at org.apache.catalina.core.AsyncContextImpl.doInternalDispatch(AsyncContextImpl.java:337)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:165)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:237)
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:242)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:57)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1790)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
2023-09-11T10:48:54,455 ERROR [http-nio-8082-exec-2] log: Exception Processing ErrorPage[errorCode=0, location=/error]
java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getHttpServletMapping()Ljavax/servlet/http/HttpServletMapping;
    at org.apache.catalina.core.ApplicationHttpRequest.setRequest(ApplicationHttpRequest.java:681)
    at org.apache.catalina.core.ApplicationHttpRequest.<init>(ApplicationHttpRequest.java:103)
    at org.apache.catalina.core.ApplicationDispatcher.wrapRequest(ApplicationDispatcher.java:857)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:513)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:480)
    at org.apache.catalina.core.StandardHostValve.custom(StandardHostValve.java:355)
    at org.apache.catalina.core.StandardHostValve.status(StandardHostValve.java:237)
    at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:320)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:237)
    at org.apache.coyote.AbstractProcessor.dispatch(AbstractProcessor.java:242)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:57)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1790)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)

当前build.gradle配置:

ext {
    springVersion = '2.7.15'
}
implementation "org.springframework.boot:spring-boot-starter-web:$springVersion"
implementation "org.springframework.boot:spring-boot-starter-webflux:$springVersion"

通过gradle dependencies命令分析到,spring-boot-starter-web默认依赖spring-boot-starter-tomcat:2.7.15(对应内嵌Tomcat 9.0.79):

+--- org.springframework.boot:spring-boot-starter-web:2.7.15
|    +--- org.springframework.boot:spring-boot-starter:2.7.15 (*)
|    +--- org.springframework.boot:spring-boot-starter-json:2.7.15 (*)
|    +--- org.springframework.boot:spring-boot-starter-tomcat:2.7.15
|    |    +--- jakarta.annotation:jakarta.annotation-api:1.3.5
|    |    +--- org.apache.tomcat.embed:tomcat-embed-core:9.0.79
|    |    +--- org.apache.tomcat.embed:tomcat-embed-el:9.0.79
|    |    \--- org.apache.tomcat.embed:tomcat-embed-websocket:9.0.79
|    |         \--- org.apache.tomcat.embed:tomcat-embed-core:9.0.79
|    +--- org.springframework:spring-web:5.3.29 (*)

提问:在Gradle中如何排除该默认Tomcat依赖,再引入指定版本的Tomcat(例如spring-boot-starter-tomcat:3.1.3)?


解决方案

1. 排除默认Tomcat依赖

在build.gradle中,给spring-boot-starter-web添加依赖排除规则,去掉默认的spring-boot-starter-tomcat:

implementation("org.springframework.boot:spring-boot-starter-web:$springVersion") {
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}

2. 引入指定版本的Tomcat依赖

直接添加指定版本的spring-boot-starter-tomcat依赖即可:

implementation "org.springframework.boot:spring-boot-starter-tomcat:3.1.3"

完整修改后的build.gradle示例

ext {
    springVersion = '2.7.15'
    tomcatStarterVersion = '3.1.3'
}

// 排除web依赖中的默认Tomcat
implementation("org.springframework.boot:spring-boot-starter-web:$springVersion") {
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation "org.springframework.boot:spring-boot-starter-webflux:$springVersion"
// 引入指定版本的Tomcat starter
implementation "org.springframework.boot:spring-boot-starter-tomcat:$tomcatStarterVersion"

注意事项

  • Spring Boot 2.7.x基于Java EE(javax.servlet),而spring-boot-starter-tomcat:3.1.3对应Tomcat 10.1.x,基于Jakarta EE(jakarta.servlet),两者API包名不兼容,直接替换会引发更多依赖冲突。
  • 如果你需要升级Tomcat,建议优先选择Spring Boot 2.7.x兼容的Tomcat版本(如Tomcat 9.x的更高版本),或者直接升级Spring Boot到3.x版本(原生支持Jakarta EE)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 06:15:00