在 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
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" ...><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.9.RELEASE</version></parent><groupId>com.qcby</groupId><artifactId>wservlet</artifactId><version>0.0.1-SNAPSHOT</version><packaging>war</packaging> <!-- 打包為WAR --><dependencies><!-- Web核心依賴 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 嵌入式Tomcat設為provided(不打包) --><dependency><groupId>orgId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope> <!-- 關鍵配置 --></dependency></dependencies><build><plugins><!-- 編譯版本配置 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin><!-- Spring Boot打包插件 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
關鍵說明: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 {@Overrideprotected 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
):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Success</title>
</head>
<body><h1>Hello, 外置Tomcat!</h1>
</body>
</html>
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 的
?
?