详细介绍:Spring Boot 使用外置 Servlet 容器:从配置到部署全指南
在 Spring Boot 开发中,我们通常使用嵌入式 Servlet 容器(如 Tomcat),它能将应用打包成可执行 JAR,简化部署流程。但在某些场景下(如需要支持 JSP、复杂的容器定制或企业级部署规范),我们需要使用外置 Servlet 容器。本文将详细介绍如何配置 Spring Boot 使用外置 Tomcat,并解释其工作原理。
一、嵌入式与外置 Servlet 容器对比
特性 | 嵌入式 Servlet 容器(JAR 包) | 外置 Servlet 容器(WAR 包) |
---|---|---|
打包方式 | 可执行 JAR | WAR 包 |
容器位置 | 内置在应用中 | 独立安装在服务器上 |
JSP 支持 | 默认不支持(需额外配置) | 原生支持 |
定制灵活性 | 有限(需通过配置类) | 高(可直接修改容器配置) |
部署方式 | 直接运行 JAR 文件 | 部署到外置容器(如 Tomcat) |
适用场景 | 快速开发、微服务、简单部署 | 企业级应用、需要 JSP、复杂配置 |
二、使用外置 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;
@SpringBootApplication
public 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 的