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

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完全兼容,无需修改任何代码或依赖:

  1. 下载并启动Tomcat 9.x;
  2. 将打包好的batch-maj-park.war放入Tomcat的webapps目录;
  3. 启动Tomcat后,访问正确路径:http://localhost:8080/batch-maj-park/api/park。

方案二:升级Spring Boot到3.x

Spring Boot 3.x开始支持Jakarta Servlet API,适配Tomcat 10:

  1. 修改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>
    
  2. 重新执行mvn clean package打包War包;
  3. 部署到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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 13:54:38