首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

面試必備:Struts2 工作原理深度解析與核心組件流程圖解

     編輯:Java 綜合教學

前言

Struts2 作為經典的 MVC 框架,雖然逐漸被 Spring MVC 取代,但在存量項目維護與面試中仍佔重要地位。能否清晰闡述其核心流程——從請求進入容器到 Action 執行再到結果渲染,是考察開發者對 Web 框架底層理解的關鍵指標。本文結合源碼級組件(FilterDispatcher、ActionMapper、ActionProxy、ActionInvocation、Interceptor)詳細拆解 Struts2 的工作原理與處理流程。

一、核心處理流程(七步走)

  1. 客戶端發起請求:瀏覽器發送 HTTP 請求至 Servlet 容器(如 Tomcat)。
  2. 過濾器鏈預處理:請求經過 web.xml 配置的過濾器鏈,關鍵包含 ActionContextCleanUp(可選,用於與 SiteMesh 等框架集成)。
  3. FilterDispatcher 接管:Struts2 核心過濾器 StrutsPrepareAndExecuteFilter(Struts 2.1.3+ 版本)攔截所有匹配 /* 的請求。
  4. ActionMapper 判斷:FilterDispatcher 委託 ActionMapper 解析請求 URL,決定是否需要調用某個 Action。
  5. ActionProxy 創建:若需調用 Action,FilterDispatcher 將請求轉交給 ActionProxy。
  6. Configuration Manager 加載配置:ActionProxy 通過 Configuration Manager 讀取 struts.xml,定位目標 Action 類及攔截器棧配置。
  7. ActionInvocation 執行鏈:ActionProxy 創建 ActionInvocation 實例,按「攔截器 → Action → 攔截器」順序(責任鏈模式)執行,最終根據 struts.xml 中的 <result> 返回視圖(JSP/FreeMarker/Velocity 等)。

二、關鍵組件深度剖析

1. StrutsPrepareAndExecuteFilter(核心入口)

配置於 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 等。

2. ActionMapper(URL 到 Action 的翻譯官)

根據 struts.xml 中的 <package> namespace、<action> name、方法名約定(默認 execute()),將 /user/add.action 映射到 UserAction.add()。支持 REST 風格、動態方法調用(!methodName)等多種策略。

3. ActionInvocation & Interceptor(責任鏈核心)

ActionInvocation 維護攔截器鏈(Interceptor Stack),典型默認棧 defaultStack 包含:

  • 參數處理:ParamsInterceptor(請求參數注入 Action 屬性)
  • 文件上傳:FileUploadInterceptor
  • 驗證:ValidationInterceptor(調用 validateXxx()、validate())
  • 工作流:WorkflowInterceptor(驗證失敗返回 input 結果)
  • 異常處理:ExceptionMappingInterceptor

執行順序:before() → Action.execute() → after(),任一攔截器返回非 invocation.invoke() 結果即中斷鏈(如驗證失敗直接返回 "input")。

4. 結果渲染(Result Type)

支持多種結果類型:

  • 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

四、面試高頻追問與回答要點

Q: Struts2 如何實現參數自動注入?
A: ParamsInterceptor 在 before() 階段利用 OGNL 表達式將請求參數(request.getParameterMap())設置到 Action 的屬性或 ModelDriven 對象中。
Q: 為什麼 Struts2 的 Action 是多例(原型模式)?
A: 為了線程安全。每個請求創建新 Action 實例,避免成員變量在併發下共享導致數據錯亂。Spring MVC Controller 默認單例,需注意線程安全。
Q: 什麼是 OGNL?在 Struts2 中怎麼用?
A: Object-Graph Navigation Language,強大的表達式語言。Struts2 將 ValueStack(值棧)作為根對象,支持屬性遍歷、集合操作、投影選擇等,如 userList.{name} 獲取所有用戶名列表。
Q: 如何自定義攔截器?
A: 實現 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)的演進脈絡。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved