Spring Boot项目Jar转War部署Tomcat10遇404错误求助
问题
我有一个最初设计为批处理的项目,后续演变为带有自动机制的REST API,项目本身运行正常,但将其从Jar格式转换为War格式部署到Tomcat 10后,调用服务时出现404错误。
已进行以下配置修改:
- 在POM中设置
<packaging>war</packaging>; - 添加
spring-boot-starter-tomcat依赖并设置scope为provided; - 主类继承
SpringBootServletInitializer。
但尝试以下请求地址均返回404:
- http://localhost:8088/warname/api/park
- http://localhost:8088/warname/park
- http://localhost:8080/warname/api/park
- http://localhost:8080/api/park
项目相关配置及日志
POM配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.2</version> <relativePath/> </parent> <groupId>com.csg</groupId> <artifactId>batchMajPark</artifactId> <version>1.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>batchMajPark</name> <description>Batch Park Spring Boot</description> <properties> <java.version>11</java.version> <org.mapstruct.version>1.2.0.Final</org.mapstruct.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-batch</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> </dependencies> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties配置
server.port=8089
Controller代码
@RestController @RequestMapping("/api/park") @RequiredArgsConstructor @CrossOrigin(origins = "*") public class parkEndpoint { ... }
Tomcat启动日志
NOTE: Picked up JDK_JAVA_OPTIONS: --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/10.0.23 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Compilé Server: Jul 14 2022 08:16:11 UTC INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: 10.0.23.0 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Windows 10 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 10.0 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: C:\\Program Files\\OpenJDK\\Jdk-11.0.15 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 16.0.1+9-24 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM provider: Oracle Corporation INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\\Users\\apache-tomcat-10.0.23 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: C:\\Users\\apache-tomcat-10.0.23 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.lang=ALL-UNNAMED INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.io=ALL-UNNAMED INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util=ALL-UNNAMED INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.base/java.util.concurrent=ALL-UNNAMED INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=C:\\Users\\apache-tomcat-10.0.23\\conf\\logging.properties INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs= INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=C:\\Users\\apache-tomcat-10.0.23 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=C:\\Users\\apache-tomcat-10.0.23 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=C:\\Users\\apache-tomcat-10.0.23\\temp INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loading Apache Tomcat Native library [1.2.35] using APR version [1.7.0] INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR Features: IPv6 [true], sendfile [true], accept filters [false], random [true], UDS [true] INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.1q 5 Jul 2022] INFO [main] org.apache.coyote.AbstractProtocol.init Protocol handler initialization ["http-nio-8080"] INFO [main] org.apache.catalina.startup.Catalina.load Server initialization took [703] milliseconds INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina] INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlets Engine: [Apache Tomcat/10.0.23] INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of the archive [C:\\Users\\apache-tomcat-10.0.23\\webapps\\batch-maj-park.war] of the Web application INFO [main] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR file was éscanné for TLDs but it did not contain any, log debug mode can be enabled to get a full list of unsuccessfully scanned JARs; éviter unnecessary parsing of JARs can significantly improve
请问是否还需要添加web.xml、首页等其他配置来解决404错误?
解决方案
核心问题:版本兼容性不匹配
Spring Boot 2.7.x基于Servlet API 4.0(包前缀为javax.servlet),而Tomcat 10使用的是Jakarta Servlet API 5.0(包前缀改为jakarta.servlet),两者API包名完全不兼容,这是导致404的根本原因。不需要额外添加web.xml或首页配置,现有配置已经满足Spring Boot War部署的基础要求。
具体解决办法
方案一:降级Tomcat到9.x
Tomcat 9.x支持Servlet API 4.0,与Spring Boot 2.7.x完全兼容,无需修改任何代码或依赖:
- 下载并启动Tomcat 9.x;
- 将打包好的
batch-maj-park.war放入Tomcat的webapps目录; - 启动Tomcat后,访问正确路径:
http://localhost:8080/batch-maj-park/api/park。
方案二:升级Spring Boot到3.x
Spring Boot 3.x开始支持Jakarta Servlet API,适配Tomcat 10:
- 修改POM中的父依赖版本为3.x(例如3.2.0),同时升级Java版本到17(Spring Boot 3.x要求最低Java 17):
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.0</version> <relativePath/> </parent> <properties> <java.version>17</java.version> <!-- 其他属性保持不变 --> </properties> - 重新执行
mvn clean package打包War包; - 部署到Tomcat 10后,访问路径:
http://localhost:8080/batch-maj-park/api/park。
额外说明
application.properties中的server.port=8089在部署到外部Tomcat时会被忽略,Tomcat自身的端口(日志中显示的8080)才是实际监听端口;- 请求路径必须包含War包的部署名称
batch-maj-park(即Tomcat webapps目录下War包的文件名),这是外部Tomcat部署Web应用的默认规则。
内容的提问来源于stack exchange,提问作者Jack Boch
相关产品推荐
相关产品推荐

