1. 概述

Spring Boot 是一个“约定优于配置”的框架,能快速搭建生产就绪的 Spring 应用。而 Tomcat 作为最主流的 Java Servlet 容器之一,广泛用于企业级部署环境。

默认情况下,Spring Boot 构建的是独立运行的 JAR 应用(内嵌 Tomcat),可以直接通过 java -jar 启动。但在某些生产场景中,运维策略要求所有 Web 应用必须部署在统一管理的外部 Tomcat 实例中——比如出于安全策略、资源隔离或集中监控的需要。

此时,就需要把 Spring Boot 项目从可执行 JAR 改造成标准 WAR 包,以便部署到外部 Tomcat 容器中。本文将带你一步步完成这个改造过程,✅踩坑指南也一并奉上。


2. 创建基础 Spring Boot 项目

我们从一个最简单的 Web 项目开始,使用 Spring Boot 官方推荐的起步依赖:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>3.1.5</version> 
    <relativePath/> 
</parent> 

<dependencies>
    <dependency> 
        <groupId>org.springframework.boot</groupId> 
        <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
</dependencies>

✅ 建议始终使用 Maven Central 上最新的稳定版本。

项目结构非常标准,无需额外配置,一个 @SpringBootApplication 注解即可启用自动配置。

接下来添加一个简单的 REST 接口用于测试:

@RestController
public class TomcatController {

    @GetMapping("/hello")
    public Collection<String> sayHello() {
        return IntStream.range(0, 10)
          .mapToObj(i -> "Hello number " + i)
          .collect(Collectors.toList());
    }
}

启动方式不变,执行:

mvn spring-boot:run

访问 http://localhost:8080/hello 可看到返回 10 条问候语,说明基础功能正常。


3. 改造为 WAR 包

要让 Spring Boot 应用支持外部 Servlet 容器(如 Tomcat),必须满足 Servlet 3.0+ 规范。为此需进行以下几项关键改造:

3.1 修改打包方式为 WAR

pom.xml 中将默认的 jar 改为 war

<packaging>war</packaging>

3.2 自定义 WAR 文件名(可选但推荐)

避免版本号污染部署路径,提升可维护性:

<build>
    <finalName>spring-boot-deployment</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

3.3 添加 Tomcat 依赖并设为 provided

⚠️ 这一步很关键:运行时由外部 Tomcat 提供 Servlet API,所以依赖范围必须是 provided

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
   <scope>provided</scope>
</dependency>

✅ 这样做既能使用 Tomcat 相关功能,又不会把内嵌容器打进 WAR 包。

3.4 继承 SpringBootServletInitializer

这是 WAR 部署的核心——用于初始化 Servlet 上下文:

@SpringBootApplication
public class SpringBootTomcatApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootTomcatApplication.class, args);
    }
}

main 方法仍保留,不影响本地开发调试。

3.5 构建 WAR 包

执行命令:

mvn clean package

构建成功后,WAR 文件生成在 target/spring-boot-deployment.war

⚠️ 注意:此时应用已变为非独立模式。若仍需支持 java -jar 启动,可将 spring-boot-starter-tomcat 的 scope 改回 compile,但不推荐混用。


4. 部署到 Tomcat

4.1 准备 Tomcat 环境

  1. 下载 Apache Tomcat 9+
  2. 解压到本地目录,例如 ~/tomcat

4.2 部署 WAR 包

简单粗暴三步走:

  1. target/spring-boot-deployment.war 复制到 tomcat/webapps/ 目录
  2. 进入 tomcat/bin 目录,启动服务:
    • Windows: catalina.bat run
    • Linux/macOS: ./catalina.sh run
  3. 浏览器访问:http://localhost:8080/spring-boot-deployment/hello

如果看到 JSON 格式的 10 条 "Hello number X",说明部署成功 ✅

💡 Tomcat 会自动解压 WAR 并创建同名上下文路径。若想部署为 ROOT 应用(即 / 路径),可将 WAR 重命名为 ROOT.war


5. 总结

本文演示了如何将一个标准 Spring Boot 项目改造为可在外部 Tomcat 中部署的 WAR 包,核心要点如下:

  • ✅ 打包方式改为 war
  • ✅ 添加 spring-boot-starter-tomcat 且 scope 为 provided
  • ✅ 主类继承 SpringBootServletInitializer
  • ✅ 构建后手动部署到 Tomcat 的 webapps 目录

虽然 Spring Boot 更推荐内嵌容器的部署模式,但在传统企业环境中,WAR + 外部 Tomcat 仍是主流。掌握这种“降级”打包方式,关键时刻能少踩一个大坑。

本文完整代码示例已托管至 GitHub:https://github.com/yourname/spring-boot-deployment


原始标题:Deploy a Spring Boot WAR into a Tomcat Server