Struts2 作為經典的 Java Web MVC 框架,雖然在 Spring MVC 與 Spring Boot 浩蕩浪潮中逐漸淡出主流視野,但其設計思想仍具備極高的學習價值。本文從架構原理、核心組件、優缺點對比三個維度,為你深度剖析這個「輕量級」框架的內幕。
本質:一個基於 MVC 設計模式的 Web 應用框架,本質上相當於一個 Filter(Struts2 核心控制器 StrutsPrepareAndExecuteFilter)
角色:在 MVC 中擔任 Controller(控制器),負責接收請求、調度模型、選擇視圖
特點:輕量級(代碼量少、資源佔用低)、支持分層開發、控制數據流向
用戶請求 (.action)
↓
StrutsPrepareAndExecuteFilter (核心過濾器)
↓
ActionMapping 匹配 → ActionProxy → ActionInvocation
↓
攔截器鏈 依次執行 (pre-processing)
↓
Action.execute() 業務邏輯執行
↓
攔截器鏈 逆序執行 (post-processing)
↓
Result 視圖渲染 (JSP/Freemarker/Velocity/JSON等)
↓
響應返回用戶
Action 接口或繼承 ActionSupport)struts.xml 配置映射關係:<action name="login" class="com.demo.LoginAction">login!register.action 調用 register() 方法ModelDriven<T> 簡化表單數據綁定Struts2 的靈魂所在,實現 AOP 思想。默認攔截器棧 defaultStack 包含 20+ 個攔截器:
| 攔截器 | 功能 |
|---|---|
| params | 請求參數自動注入 Action 屬性 |
| validation | 數據校驗支持 |
| workflow | 控制流程跳轉(如校驗失敗返回 input) |
| fileUpload | 文件上傳處理 |
| i18n | 國際化支持 |
| servletConfig | 提供 Servlet API 訪問 |
| prepare | 預處理接口 Preparable 支持 |
自定義攔截器:實現 Interceptor 接口,在 struts.xml 中註冊並加入攔截器棧。
dispatcher (默認):JSP 頁面跳轉redirect:重定向redirectAction:重定向到另一 Actionjson:JSON 數據返回(需 json-plugin)stream:文件下載/圖片輸出freemarker/velocity:模板引擎渲染#request.key、#session.userlist[0].property、map.keyuser.getFullName()ValueStack 存放 Action 實例及上下文對象,OGNL 從中查找數據Action 是 POJO,業務邏輯與框架解耦,易於單元測試,程序員專注業務實現。
實現 AOP,橫切關注點(權限、日誌、事務、編碼)集中管理,defaultStack 開箱即用。
UI 標簽(form、select、iterator)、數據標簽(property、if/else)、控制標簽極大提升開發效率。
struts.xml 集中管理 URL 映射、結果視圖、攔截器棧、異常處理,系統關係一目了然。
核心 struts-default.xml 定義默認 Bean/結果類型/攔截器棧,均可通過配置覆蓋或插件擴展。
配置文件聲明式異常映射:<exception-mapping exception="java.sql.SQLException" result="db-error" />
Action 屬性同時用於接收請求參數和輸出數據到視圖,屬性膨脹導致類臃腫,職責不清。
複雜表達式解析開銷大,曾爆出多個安全漏洞(如 S2-045、S2-057),需持續升級修補。
值棧、OGNL、上下文映射關係複雜,新手易踩坑(如同名屬性遮蔽、集合索引越界)。
基於 *.action 後綴映射,REST 風格 URL 需額外配置,不如 Spring MVC 自然。
Spring MVC/Boo已成主流,Struts2 新版本迭代緩慢,招聘需求銳減,文檔資源相對匱乏。
Struts2 承載了 Java Web 發展的輝煌歷程,其設計精髓(Front Controller、Interceptor Chain、配置驅動)深深影響了後續框架。了解它,是向經典致敬,更是為了更好地駕馭現代框架。