Spring Boot 使用外置 Servlet 容器:从配置到部署全指南
在 Spring Boot 开发中,我们通常使用嵌入式 Servlet 容器(如 Tomcat),它能将应用打包成可执行 JAR,简化部署流程。但在某些场景下(如需要支持 JSP、复杂的容器定制或企业级部署规范),我们需要使用外置 Servlet 容器。本文将详细介绍如何配置 Spring Boot 使用外置 Tomcat,并解释其工作原理。
一、嵌入式与外置 Servlet 容器对比
二、使用外置 Servlet 容器的步骤
1. 创建 WAR 项目
首先,需要创建一个 WAR 类型的 Maven 项目。在 IDEA 中,可通过以下方式配置:
- 新建项目时选择 \"Spring Initializr\"
- 打包方式选择 \"War\"
- 勾选 \"Spring Web\" 依赖
项目结构如下(重点关注与 JSP 相关的目录):
wservlet/├── src/│ ├── main/│ │ ├── java/│ │ │ └── com/qcby/wservlet/│ │ │ ├── controller/ // 控制器│ │ │ ├── WservletApplication.java // 主程序类│ │ │ └── ServletInitializer.java // 外置容器启动器│ │ ├── resources/│ │ │ └── application.properties // 配置文件│ │ └── webapp/ // Web资源目录(外置容器必需)│ │ ├── WEB-INF/│ │ │ └── jsp/ // JSP页面目录│ │ └── WEB-INF/web.xml // Web配置(可选)│ └── pom.xml // 依赖配置
2. 配置依赖(pom.xml)
核心是将嵌入式 Tomcat 设置为provided
(仅编译时生效,不打包到 WAR 中),并指定打包方式为war
:
4.0.0 org.springframework.boot spring-boot-starter-parent 1.5.9.RELEASE com.qcby wservlet 0.0.1-SNAPSHOT war org.springframework.boot spring-boot-starter-web orgId>org.springframework.boot spring-boot-starter-tomcat provided org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8 org.springframework.boot spring-boot-maven-plugin
关键说明:provided
scope 确保嵌入式 Tomcat 不会被打包到 WAR 中,避免与外置容器冲突。
配置项目的目录结构
3. 编写 ServletInitializer 类
外置容器启动时,不会执行 Spring Boot 主类的main
方法,而是通过SpringBootServletInitializer
子类初始化应用。因此需要创建该类:
package com.qcby.wservlet;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.boot.web.support.SpringBootServletInitializer;// 继承SpringBootServletInitializer,用于外置容器启动public class ServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { // 传入Spring Boot主程序类,关联应用上下文 return application.sources(WservletApplication.class); }}
作用:相当于传统 Web 项目的web.xml
,负责在容器启动时加载 Spring Boot 应用。
4. 配置主程序类
主程序类与普通 Spring Boot 应用一致,但需确保@SpringBootApplication
注解正确:
package com.qcby.wservlet;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class WservletApplication { // 主方法(嵌入式容器启动入口,外置容器时不执行) public static void main(String[] args) { SpringApplication.run(WservletApplication.class, args); }}
5. 配置 JSP 视图(可选)
外置容器天然支持 JSP,需在application.properties
中配置视图解析器:
# 应用名称spring.application.name=wservlet# JSP视图配置spring.mvc.view.prefix=/WEB-INF/jsp/ # JSP文件存放路径spring.mvc.view.suffix=.jsp # 视图后缀
创建 JSP 页面(src/main/webapp/WEB-INF/jsp/suc.jsp
):
Success Hello, 外置Tomcat!
6. 创建控制器
编写一个简单的控制器,映射请求到 JSP 视图:
package com.qcby.wservlet.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;@Controller@RequestMapping(\"/suc\")public class SucController { // 映射路径:/suc/index @RequestMapping(\"/index\") public String index() { System.out.println(\"访问suc页面\"); return \"suc\"; // 对应WEB-INF/jsp/suc.jsp }}
7. 部署到外置 Tomcat
-
下载并安装 Tomcat:从官网下载 Tomcat(建议 8.5 + 版本),解压到本地目录。
-
打包 WAR 文件:
- 在 IDEA 中执行
mvn clean package
,生成 WAR 包(位于target/wservlet-0.0.1-SNAPSHOT.war
)。 - 可将 WAR 包重命名为简化名称(如
wservlet.war
)。
- 在 IDEA 中执行
-
部署到 Tomcat:
- 将 WAR 包复制到 Tomcat 的
webapps
目录下。 - 启动 Tomcat(执行
bin/startup.bat
或bin/startup.sh
)。 - Tomcat 会自动解压 WAR 包并部署应用。
- 将 WAR 包复制到 Tomcat 的
-
访问应用:
- 地址格式:
http://localhost:8080/[WAR包名称]/[请求路径]
- 示例:
http://localhost:8080/wservlet/suc/index
,将显示 JSP 页面内容。
- 地址格式:
三、工作原理:JAR 与 WAR 启动差异
-
JAR 包启动(嵌入式容器):
- 执行
main
方法,通过SpringApplication.run()
启动 IOC 容器。 - 自动创建嵌入式 Servlet 容器(如 Tomcat),并将应用部署到该容器。
- 执行
-
WAR 包启动(外置容器):
- 外置容器(如 Tomcat)启动时,会扫描
webapps
目录下的 WAR 包。 - 执行
ServletInitializer
的configure
方法,初始化 Spring 应用上下文。 - 由外置容器接管请求处理,不再依赖嵌入式容器。
- 外置容器(如 Tomcat)启动时,会扫描
核心区别:外置容器的生命周期由容器本身管理,Spring Boot 应用作为 Web 应用被部署,而非作为独立进程运行。
四、常见问题与解决方案
-
JSP 页面 404 错误:
- 检查
spring.mvc.view.prefix
是否正确(需对应webapp/WEB-INF/jsp/
)。 - 确保
webapp
目录在src/main
下(IDEA 默认资源目录)。
- 检查
-
依赖冲突:
- 避免引入与外置容器版本冲突的依赖(如不同版本的 Tomcat API)。
- 确保
spring-boot-starter-tomcat
的 scope 为provided
。
-
访问路径问题:
- 外置容器部署时,应用上下文路径为 WAR 包名称(可在 Tomcat 的
server.xml
中自定义)。
- 外置容器部署时,应用上下文路径为 WAR 包名称(可在 Tomcat 的