前言
「Tomcat 控制台無錯誤、啟動耗時正常,但訪問任意頁面 (含靜態資源) 全部返回 404」是 Java Web 開發中極高頻的詭異現象。本文從 **Eclipse 部署配置、專案結構、Web.xml 映射、Maven 打包、Server.xml 殘留** 五大維度,提供系統性排查清單與根因修復方案。
現象定義
- ✅ Tomcat 啟動日誌無 `SEVERE`、`ERROR`,端口監聽正常 (netstat -an | findstr 8080)。
- ✅ 訪問 `https://localhost:8080/` 顯示 Tomcat 預設首頁 (ROOT 應用正常)。
- ❌ 訪問 `https://localhost:8080/your-app/...` **全部 404**,包括 JSP、HTML、CSS、JS、Servlet、Controller。
- ❌ Tomcat `webapps` 目錄下**看不到**你的專案資料夾或 WAR 包。
核心原因排查清單 (按命中率排序)
1. Eclipse Server Location 配置錯誤 (最高發,佔 60%+)
現象:使用 Eclipse 內嵌 Tomcat 開發時,預設 `Server location` 為 `Use workspace metadata`,導致部署路徑指向 `.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps`,而非 Tomcat 安裝目錄 `webapps`。若專案未正確發布到該臨時目錄,即 404。
修復步驟:
- Eclipse `Servers` 視圖雙擊 Tomcat Server 打開編輯器。
- 切換到 `Server Locations` 區段。
- 選中 `Use Tomcat installation` (使用 Tomcat 安裝目錄)。
- 勾選 `Deploy path: webapps` (可選,預設即是)。
- 關鍵: 刪除 Server 視圖中該 Server 的所有部署資源 → `Clean` → `Clean Tomcat Work Directory` → 重新啟動。
原理:`Use workspace metadata` 會將應用部署到工作區元數據目錄,且不支援熱部署 JSP 修改。`Use Tomcat installation` 直接部署到標準 `webapps`,行為與生產環境一致,強烈建議**永久切換到此模式**。
2. 專案未加入 Server 部署清單 (佔 20%)
現象:專案建立後未關聯到 Server,或關聯後被誤移除 (如原文所述「刪 jar 包時不小心把發布所包含的 webapp給 remove 掉了」)。
檢查/修復:
- Server 視圖右鍵 Tomcat → `Add and Remove...`
- 確保目標專案在 `Configured` 列表中 (若在 `Available` 雙擊移過去)。
- 若專案已在列表但仍 404:移除 → `Clean` → 重新加入 → `Clean Tomcat Work Directory` → 重啟。
3. Maven 專案:Deployment Assembly 缺失依賴 (佔 15%)
現象:`pom.xml` 引入的 jar (如 `servlet-api`, `spring-webmvc`, `mybatis`) 未隨 WAR 打包進 `WEB-INF/lib`,導致類加載失敗,但 Tomcat 不報錯直接 404 (Servlet 未註冊)。
修復:
- 專案右鍵 → `Properties` → `Deployment Assembly`。
- 點 `Add...` → `Java Build Path Entries` → 選中 `Maven Dependencies` (或具體 Library)。
- 確認 `Deploy Path` 為 `WEB-INF/lib`。
- 若用 `mvn war:war` 打包,檢查 `target/your-app/WEB-INF/lib` 是否包含所有依賴。
4. web.xml / Servlet 映射錯誤 / 衝突
- Servlet `url-pattern` 寫錯 (如 `/api/*` 卻訪問 `/api/user` 少了斜槓)。
- Spring MVC `DispatcherServlet` 映射為 `/` 而非 `/*`,導致靜態資源被攔截 (需配置 `` 或 `resource-handler`)。
- 多個 Servlet 映射衝突,優先級導致預期 Servlet 不生效。
5. server.xml 殘留 Context 配置干擾
若手動修改過 `conf/server.xml` 添加 ``,且同時 Eclipse 又管理部署,**會產生雙重部署或路徑衝突**。原則:開發環境禁用 server.xml 手動配 Context,完全交給 Eclipse/IDE 管理。
6. 專案結構不符合 Servlet 規範
- 非 Maven 專案:`WebContent/WEB-INF/web.xml` 缺失或位置錯誤。
- Maven 專案:`src/main/webapp/WEB-INF/web.xml` 缺失 (Servlet 3.0+ 可無,但需註解配置完整)。
- 輸出目錄非 `target/classes` 或 `WEB-INF/classes`。
系統性排查步驟 (標準作業程序 SOP)
- 確認部署實體:進入 Tomcat 實際部署目錄 (`webapps` 或 `wtpwebapps`),查看是否存在專案資料夾/war,結構是否完整 (`WEB-INF/classes`, `WEB-INF/lib`, `web.xml`)。
- 檢查啟動日誌:搜尋專案名關鍵字,確認是否有 `Deploying web application directory...`、`Initializing Spring FrameworkServlet` 等載入日誌。無日誌 = 未部署。
- 訪問靜態資源:嘗試訪問 `https://localhost:8080/your-app/test.html` (新建一個靜態 HTML 放在 webapp 根目錄)。若靜態也 404 → **部署失敗/路徑錯**;若靜態正常、動態 404 → **Servlet/映射/框架配置錯**。
- 清理重建:`Server` → `Clean` → `Clean Tomcat Work Directory` → `Project` → `Clean` → `Maven` → `Update Project` → 重啟 Server。
- 切換部署模式:按原因 1 切換至 `Use Tomcat installation`,徹底解決 Eclipse 元數據部署諸多怪病。
進階:遠端除錯 404 根因
若上述無效,啟用 Tomcat 遠端除錯 (`-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000`),在 `org.apache.catalina.mapper.Mapper.internalMapWrapper` 或 `StandardContextValve.invoke` 打斷點,觀察請求映射路徑解析過程,可精確定位是 Context 找不到、Wrapper 找不到、還是 Filter 鏈攔截。
總結
Tomcat 啟動正常但全站 404,**核心 90% 是「應用未真正部署到生效目錄」**。請死磕 Eclipse Server Location 設為 `Use Tomcat installation`、**專案確實在 Server 部署清單中**、**Maven Deployment Assembly 包含依賴** 這三大鐵律。配合 `Clean` 大法,可解決絕大多數疑難雜症。