核心流程圖
客戶端請求
↓
[1] 過濾器鏈
↓
[2] FilterDispatcher (核心控制器)
↓
[3] ActionMapper → 決定是否調用 Action
↓
[4] ActionProxy (動態代理)
↓
[5] Configuration Manager (struts.xml) → 定位 Action 類
↓
[6] ActionInvocation (命令模式)
↓
[7] 攔截器鏈 → Action 執行 → 攔截器鏈
↓
[8] Result (結果視圖) → JSP / Action 鏈 / 流等
↓
客戶端響應
八大步驟詳細解析
步驟 1:過濾器鏈預處理
- 請求首先通過
web.xml 配置的過濾器。
- 關鍵過濾器:
ActionContextCleanUp(可選,清理 ThreadLocal)、其他業務過濾器、最後是 FilterDispatcher(Struts2 核心入口)。
步驟 2:FilterDispatcher 接管請求
- 作為前端控制器,統一接收所有進入 Struts2 的請求。
- 委派給
ActionMapper 判斷是否需要處理。
步驟 3:ActionMapper 路由決策
- 根據 URL 模式(
*.action、REST 風格等)決定是否映射到 Action。
- 若否,放行給其他 Servlet/靜態資源處理。
步驟 4:ActionProxy 動態代理
- 創建
ActionProxy 實例,封裝調用邏輯。
- 實現「代理模式」:預處理、事務、異常統一攔截。
步驟 5:Configuration Manager 讀取配置
- 解析
struts.xml(及插件配置),構建 ActionConfig、ResultConfig、InterceptorStack 等元數據。
- 緩存配置,熱加載由
ConfigurationManager 監控文件變更。
步驟 6:ActionInvocation 命令模式
- 創建
ActionInvocation,持有 Action、攔截器鏈、結果配置。
- 調用
invoke() 觸發責任鏈執行。
步驟 7:攔截器鏈與 Action 執行
// 簡化版 invoke() 邏輯
public String invoke() throws Exception {
if (interceptors.hasNext()) {
Interceptor interceptor = interceptors.next();
return interceptor.intercept(this); // 責任鏈傳遞
}
// 所有攔截器通過,執行 Action
result = action.execute();
return result;
}
- 默認攔截器棧:
defaultStack(params、prepare、validation、workflow 等)。
- Action 執行前後分別經歷「前置攔截」與「後置攔截」。
步驟 8:結果視圖渲染
- Action 返回邏輯視圖名(如
"success")。
ActionInvocation 根據 struts.xml 映射找到 Result 實現:
| Result 類型 | 用途 |
| dispatcher (默認) | 轉發到 JSP |
| redirect | 重定向 |
| chain | Action 鏈調用 |
| stream | 文件下載/圖片輸出 |
| json | REST API 返回 JSON |
| freemarker/velocity | 模板引擎 |
關鍵設計模式總結
| 模式 | 應用位置 |
| 前端控制器 | FilterDispatcher |
| 動態代理 | ActionProxy |
| 命令模式 | ActionInvocation |
| 責任鏈 | 攔截器鏈 |
| 工廠模式 | ObjectFactory 創建 Action/Interceptor |
常見面試考點
- Struts2 如何實現線程安全? Action 多例,每請求一實例;攔截器單例但無狀態。
- 值棧作用? OGNL 表達式存取數據的上下文棧,Action 實例壓入棧頂。
- 攔截器 vs 過濾器? 攔截器基於 Struts2 內部,可訪問 Action/值棧;過濾器基於 Servlet API,更底層。
- 如何自定義攔截器? 實現
Interceptor 接口,配置進 struts.xml 的 <interceptor-stack>。
總結
Struts2 以 FilterDispatcher 為入口,通過 ActionMapper → ActionProxy → ActionInvocation → Interceptor Stack → Action → Result 的標準化流程,實現了請求處理的高度解耦與擴展。理解這八步,即掌握了 Struts2 的靈魂架構。