Struts 2 是基於 MVC 模式的 Web 層框架,通過攔截器機制實現請求處理流程的可插拔擴展,核心優勢在於 Action 與 Servlet API 解耦,便於單元測試與類型轉換。
Servlet 開發痛點:web.xml 配置繁瑣、難以分組開發、HttpServletRequest/Response 與容器強耦合導致測試困難、單 Servlet 多方法需手動分發。Struts 2 通過過濾器攔截請求、OGNL 表達式綁定參數、結果類型多樣化等機制解決上述問題。
StrutsPrepareAndExecuteFilter(2.1.3+ 版本)啟動,prepare 階段加載配置,execute 階段調用 doFilter;ActionMapper 判斷是否需調用 Action;ActionProxy 通過 ConfigurationManager 定位 Action 類;ActionInvocation,按攔截器鏈調用(AOP 思想,Action 方法為切點);ActionInvocation 根據 struts.xml 尋找 Result(JSP/FreeMarker/Action 鏈);ObjectFactory 創建,支持 Spring 整合。

內置 35+ 攔截器(如 validation、fileUpload),組成 defaultStack。自定義步驟:實現 Interceptor 接口 → 重寫 intercept() → struts.xml 註冊 → <interceptor-ref> 引用。注意:引用自定義攔截器會覆蓋默認棧,建議組合使用:
<interceptor-ref name="defaultStack"/> <interceptor-ref name="myInterceptor"/>
ActionSupport,重寫 validate()(所有方法)或 validateXxx()(指定方法),調用 addFieldError();ActionName-validation.xml 或 ActionName-methodName-validation.xml,使用內置驗證器(requiredstring、int 等);FieldValidatorSupport,註冊至 validators.xml。| 屬性驅動 | 模型驅動 |
|---|---|
| Action 直接定義字段 + getter/setter | 實現 ModelDriven<T>,getModel() 返回 JavaBean |
| 適合表單字段與持久層不一致場景 | 適合字段一一對應,代碼更整潔 |
ParametersInterceptor 自動賦值 | ModelDrivenInterceptor 將模型壓入值棧頂 |
建議專案統一風格:若持久層對象與表單一致用模型驅動,否則用屬性驅動。
請求參數均為 String,非 String 類型需轉換。自定義轉換器繼承 DefaultTypeConverter,重寫 convertValue()。註冊方式:
ActionName-conversion.properties,field=ConverterClass;xwork-conversion.properties,TargetType=ConverterClass。轉換失敗自動跳轉 input 結果頁。
OGNL(Object-Graph Navigation Language)是 Struts 2 默認表達式語言。ValueStack 接口實現類 OgnlValueStack 貫穿 Action 生命周期,保存 Action 實例及相關對象,存放於 request 域 struts.valueStack。ActionContext 通過 ThreadLocal 綁定線程上下文,其 context 即 OgnlContext,包含 request、session、application、parameters 等 Map 及 ValueStack。值棧內部 CompoundRoot 維護對象層級,OGNL 表達式從棧頂向下查找屬性。
