Struts2 作為經典的 MVC 框架,雖然逐漸被 Spring MVC 取代,但在存量項目維護與面試中仍佔重要地位。能否清晰闡述其核心流程——從請求進入容器到 Action 執行再到結果渲染,是考察開發者對 Web 框架底層理解的關鍵指標。本文結合源碼級組件(FilterDispatcher、ActionMapper、ActionProxy、ActionInvocation、Interceptor)詳細拆解 Struts2 的工作原理與處理流程。
web.xml 配置的過濾器鏈,關鍵包含 ActionContextCleanUp(可選,用於與 SiteMesh 等框架集成)。StrutsPrepareAndExecuteFilter(Struts 2.1.3+ 版本)攔截所有匹配 /* 的請求。ActionMapper 解析請求 URL,決定是否需要調用某個 Action。ActionProxy。Configuration Manager 讀取 struts.xml,定位目標 Action 類及攔截器棧配置。ActionInvocation 實例,按「攔截器 → Action → 攔截器」順序(責任鏈模式)執行,最終根據 struts.xml 中的 <result> 返回視圖(JSP/FreeMarker/Velocity 等)。配置於 web.xml:
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Prepare 階段(初始化配置、構建 ActionMapping);Execute 階段(執行 ActionInvocation)。struts.action.excludePattern 排除 .css/.js/.png 等。根據 struts.xml 中的 <package> namespace、<action> name、方法名約定(默認 execute()),將 /user/add.action 映射到 UserAction.add()。支持 REST 風格、動態方法調用(!methodName)等多種策略。
ActionInvocation 維護攔截器鏈(Interceptor Stack),典型默認棧 defaultStack 包含:
ParamsInterceptor(請求參數注入 Action 屬性)FileUploadInterceptorValidationInterceptor(調用 validateXxx()、validate())WorkflowInterceptor(驗證失敗返回 input 結果)ExceptionMappingInterceptor執行順序:before() → Action.execute() → after(),任一攔截器返回非 invocation.invoke() 結果即中斷鏈(如驗證失敗直接返回 "input")。
支持多種結果類型:
dispatcher(默認,轉發到 JSP)redirect / redirectAction(重定向)freemarker / velocity / jasper(報表)stream(文件下載)json(Struts2 JSON Plugin,AJAX 專用)| 文件 | 核心職責 | 關鍵配置示例 |
|---|---|---|
| web.xml | 啟動核心 Filter,定義攔截路徑 | <filter-class>StrutsPrepareAndExecuteFilter</filter-class> |
| struts.xml | 定義 Package/Action/Result/Interceptor Stack | <action name="login" class="com.xxx.LoginAction" method="execute"><result>/success.jsp</result></action> |
| struts.properties / struts-default.xml | 框架級默認配置(國際化、主題、開發模式等) | struts.devMode=true |
ParamsInterceptor 在 before() 階段利用 OGNL 表達式將請求參數(request.getParameterMap())設置到 Action 的屬性或 ModelDriven 對象中。userList.{name} 獲取所有用戶名列表。Interceptor 接口(init()、destroy()、intercept(ActionInvocation)),在 struts.xml 中 <interceptor> 定義並加入自定義棧或直接引用。Struts2 以 Filter 為入口,通過 ActionMapper 解析請求,ActionProxy 代理執行,ActionInvocation 驅動攔截器鏈與 Action 業務邏輯,最終由 Result 渲染視圖。其設計精髓在於:核心組件解耦(Filter/Mapper/Proxy/Invocation/Interceptor/Result)、OGNL 驅動的數據綁定、攔截器鏈實現橫切關注點。理解這套機制,不僅能應付面試,更能洞察現代 Web 框架(Spring MVC、WebFlux)的演進脈絡。