Spring Boot 3 WAR包无法在Tomcat 10/11运行的原因排查
1. Spring Boot 3 是否可以在 Tomcat 10/11 运行?
可以,但核心前提是Spring Boot 3 基于 Jakarta EE 9+,而 Tomcat 10/11 是首个支持 Jakarta EE 规范的 Tomcat 版本(Tomcat 9 及以下仅支持 Java EE),二者规范兼容,只要配置正确就能正常运行。
2. 你可能缺失的配置/依赖
结合你遇到的“部署显示运行但访问404、无错误日志”现象,大概率是以下几个关键配置没做好:
(1)设置打包方式为 WAR
Spring Boot 默认打包为可执行 JAR,部署到外部 Tomcat 必须改为 WAR 包,在 pom.xml 中添加:
<packaging>war</packaging>
(2)排除内置 Tomcat 依赖
避免与外部 Tomcat 冲突,在 spring-boot-starter-web 中排除内置 Tomcat:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency>
(3)添加 Tomcat 依赖(编译期用)
如果需要在本地编译时依赖 Tomcat API,可添加 provided 范围的依赖(避免打包进 WAR):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
(4)启动类继承 SpringBootServletInitializer
这是部署外部 Tomcat 的必要步骤,让 Spring Boot 适配 Servlet 容器启动流程:
@SpringBootApplication public class YourAppApplication extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(YourAppApplication.class); } public static void main(String[] args) { SpringApplication.run(YourAppApplication.class, args); } }
(5)替换所有 Java EE 旧 API
确保项目中没有使用 javax.servlet.*、javax.persistence.* 等旧 Java EE 包,全部替换为 jakarta.servlet.*、jakarta.persistence.* 等 Jakarta EE 包——Spring Boot 3 已彻底移除对 Java EE API 的支持。
3. Spring Tomcat 依赖是否支持 Tomcat 10/11?
支持。Spring Boot 3 对应的 spring-boot-starter-tomcat 依赖本身就是基于 Jakarta EE 规范构建的:
- Spring Boot 3.0.x 适配 Tomcat 10.1.x
- Spring Boot 3.1.x 适配 Tomcat 10.1.x
- Spring Boot 3.2.x 适配 Tomcat 11.0.x
完全兼容 Tomcat 10/11 的运行环境。
额外排查建议
- 确认访问路径:如果 WAR 包名称不是
ROOT.war,访问时需要加上包名(比如http://localhost:8080/your-app-name) - 检查 Tomcat
webapps目录:确认 WAR 包已正确解压为对应文件夹 - 查看 Tomcat 日志:重点看
localhost.log、localhost_access_log.*.txt,确认请求是否到达容器、路径是否匹配 - 验证项目配置:确保
application.properties/yml中没有设置冲突的server.port、server.servlet.context-path等参数
内容的提问来源于stack exchange,提问作者user2694740

