Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。struts使系統的脈絡更加清晰。通過一個配置文件,即可把握整個系統各部分之間的聯系,這對於后期的維護有着莫大的好處。
Struts 2 相比Struts 1的優點:
1、在軟件設計上Struts 2 沒有像Struts 1那樣跟Servlet API 和 struts API 有着緊密的耦合。
Struts 2的應用可以不依賴於Servlet API和Struts API 。
2、Struts 2 提供了攔截器,利用攔截器可以進行AOP編程。
3、Struts 2 提供了類型轉換器。
4、Struts 2 提供支持多種表現層技術,如:JSP 、 freeMarker等。
5、Struts 2 的輸入校驗可以指定方法進行校驗。
6、Struts 2 提供了全局范圍、包范圍和Action范圍的國際化資源文件管理實現。
struts2 的工作原理:
1、客戶端初始化一個指向Servlet容器(例如Tomcat)的HttpServletRequest請求
2、這個請求經過一系列的過濾器(Filter)【ActionContextCleanUp的可選過濾器(延長action中屬性的生命周期,包括自定義屬性,以便在jsp頁面中進行訪問,讓actionContextcleanup過濾器來清除屬性,不讓action自己清除)】
3、接着FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action
4、如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy
5、ActionProxy通過ConfigurationManager詢問框架的配置文件,找到需要調用的Action類 ,這里,我們一般是從struts.xml配置中讀取。
6、ActionProxy創建一個ActionInvocation的實例。
7、ActionInvocation實例使用命名模式來調用,在調用Action的過程前后,涉及到相關攔截器(Intercepter)的調用。
ActionInvocation是Xworks 中Action 調度的核心。而對Interceptor 的調度,也正是由ActionInvocation負責。ActionInvocation 是一個接口,而 DefaultActionInvocation 則是Webwork 對ActionInvocation的默認實現。
Interceptor的調度流程大致如下:
1.ActionInvocation初始化時,根據配置,加載Action相關的所有Interceptor。
2. 通過ActionInvocation.invoke方法調用Action實現時,執行Interceptor。
8、一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 框架中繼承的標簽。在這個過程中需要涉及到ActionMapper
struts2 攔截器
攔截器是在訪問某個Action或Action的某個方法,字段之前或之后實施攔截,並且Struts2攔截器是可插拔的,攔截器是aop的一種實現
攔截器棧(Interceptor Stack)。Struts2攔截器棧就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,Struts2攔截器鏈中的攔截器就會按其之前定義的順序被調用
工作原理:
攔截器實現類
struts2規定用戶自定義攔截器必須實現com.opensymphony.xwork2.interceptor.Interceptor接口。
該接口聲明了3個方法
void init();
void destroy();
String intercept(ActionInvocation invocation) throws Exception;
【抽象類AbstractInterceptor實現了Interceptor接口,提供了init和destroy方法的空實現。如果我們的攔截器不需要打開資源,則可以無需實現這兩個方法。可通過繼承AbstractInterceptor抽象類來實現自定義攔截器會更簡單】
1 package interceptor; 2 import com.opensymphony.xwork2.ActionInvocation; 3 import com.opensymphony.xwork2.interceptor.Interceptor; 4 public class MyInterceptor implements Interceptor { 5 public void destroy() { 6 // TODO Auto-generated method stub 7 } 8 public void init() { 9 // TODO Auto-generated method stub 10 } 11 public String intercept(ActionInvocation invocation) throws Exception { 12 System.out.println("Action執行前插入 代碼"); 13 //執行目標方法 (調用下一個攔截器, 或執行Action) 14 final String res = invocation.invoke(); 15 System.out.println("Action執行后插入 代碼"); 16 return res; 17 }
18 }
自定義攔截器,攔截器
1 <package name="custom" extends="struts-default" namespace="/">
2 <interceptors>
3 <!-- 定義攔截器 -->
4 <interceptor name="攔截器名" class="攔截器實現類"/>
5 <!-- 定義攔截器棧 -->
6 <interceptor-stack name="攔截器棧名">
7 <interceptor-ref name="攔截器一"/>
8 <interceptor-ref name="攔截器二"/>
9 </interceptor-stack>
10 </interceptors>
11
12 </package>
使用攔截器
1 <action name="user" class="com.userAction"> 2 <result name="success">/success.jsp</result> 3 <result name="error">/error.jsp</result> 4 <!-- 使用攔截器,一般配置在result之后, --> 5 <!-- 引用系統默認的攔截器 --> 6 <interceptor-ref name="defaultStack"/> 7 <interceptor-ref name="攔截器名或攔截器棧名"/> 8 </action>
如果為Action指定了一個攔截器,則系統默認的攔截器棧將會失去作用。為了繼續使用默認攔截器,需要在自己定義的攔截器棧中手動引入了默認攔截器。
【默認的攔截器中有一個名為params的攔截器,它的作用是“將請求的參數設置到Action中”,也就是說,如果你從頁面中傳值到Action,即攔截請求參數,並賦值給action里的屬
性,而且你自定義的攔截器要用到這些值棧中的值,則你的攔截器棧中,需要在自定義攔截器前面加上默認的攔截器】
struts2 已經為您提供豐富多樣的,功能齊全的攔截器實現。在struts2的jar包內的struts-default.xml可以查看到關於默認的攔截器與攔截器鏈的配置。
攔截器 |
名字 |
說明 |
Alias Interceptor |
alias |
在不同請求之間將請求參數在不同名字件轉換,請求內容不變 |
Chaining Interceptor |
chain |
讓前一個Action的屬性可以被后一個Action訪問,現在和chain類型的result(<result type=”chain”>)結合使用。 |
Checkbox Interceptor |
checkbox |
添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定為false,而html默認情況下不提交沒有選中的checkbox。 |
Cookies Interceptor |
cookies |
使用配置的name,value來是指cookies |
Conversion Error Interceptor |
conversionError |
將錯誤從ActionContext中添加到Action的屬性字段中。 |
Create Session Interceptor |
createSession |
自動的創建HttpSession,用來為需要使用到HttpSession的攔截器服務。 |
Debugging Interceptor |
debugging |
提供不同的調試用的頁面來展現內部的數據狀況。 |
Execute and Wait Interceptor |
execAndWait |
在后台執行Action,同時將用戶帶到一個中間的等待頁面。 |
Exception Interceptor |
exception |
將異常定位到一個畫面 |
File Upload Interceptor |
fileUpload |
提供文件上傳功能 |
I18n Interceptor |
i18n |
記錄用戶選擇的locale |
Logger Interceptor |
logger |
輸出Action的名字 |
Message Store Interceptor |
store |
存儲或者訪問實現ValidationAware接口的Action類出現的消息,錯誤,字段錯誤等。 |
Model Driven Interceptor |
model-driven |
如果一個類實現了ModelDriven,將getModel得到的結果放在Value Stack中。 |
Scoped Model Driven |
scoped-model-driven |
如果一個Action實現了ScopedModelDriven,則這個攔截器會從相應的Scope中取出model調用Action的setModel方法將其放入Action內部。 |
Parameters Interceptor |
params |
將請求中的參數設置到Action中去。 |
Prepare Interceptor |
prepare |
如果Acton實現了Preparable,則該攔截器調用Action類的prepare方法。 |
Scope Interceptor |
scope |
將Action狀態存入session和application的簡單方法。 |
Servlet Config Interceptor |
servletConfig |
提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問。 |
Static Parameters Interceptor |
staticParams |
從struts.xml文件中將<action>中的<param>中的內容設置到對應的Action中。 |
Roles Interceptor |
roles |
確定用戶是否具有JAAS指定的Role,否則不予執行。 |
Timer Interceptor |
timer |
輸出Action執行的時間 |
Token Interceptor |
token |
通過Token來避免雙擊 |
Token Session Interceptor |
tokenSession |
和Token Interceptor一樣,不過雙擊的時候把請求的數據存儲在Session中 |
Validation Interceptor |
validation |
使用action-validation.xml文件中定義的內容校驗提交的數據。 |
Workflow Interceptor |
workflow |
調用Action的validate方法,一旦有錯誤返回,重新定位到INPUT畫面 |
Parameter Filter Interceptor |
N/A |
從參數列表中刪除不必要的參數 |
Profiling Interceptor |
profiling |
通過參數激活profile
|
如果為了簡化struts.xml文件的配置,避免在每個Action重復配置該攔截器,可以將攔截器配置成了一個默認攔截器棧
1 <struts> 2 <package name="test" extends="struts-default" namespace="/"> 3 4 <interceptors> 5 <!-- 定義攔截器 --> 6 <interceptor name="customInterceptor" 7 class="com.testInterceptor" /> 8 <!-- 定義一個攔截器棧 --> 9 <interceptor-stack name="mydefault"> 10 <interceptor-ref name="defaultStack" /> 11 <interceptor-ref name="customInterceptor" /> 12 </interceptor-stack> 13 </interceptors> 14 15 <!-- 定義默認攔截器 --> 16 <default-interceptor-ref name="mydefault" /> 17 18 <!-- 定義全局處理結果 --> 19 <global-results> 20 <!-- 邏輯名為login的結果,映射到/login.jsp頁面 --> 21 <result name="login">/login.jsp</result> 22 </global-results> 23 24 <action name="user" class="com.UserAction" > 25 <result name="success">/success.jsp</result> 26 </action> 27 </package> 28 29 <package name="test1" extends="struts-default" namespace="/"> 30 <action name="admin" class="com.UserAction" > 31 <result name="success">/success.jsp</result> 32 </action> 33 </package> 34 </struts>
一旦在某個包下定義了默認攔截器棧,在該包下的所有action都會使用此攔截器棧。對於那些不想使用這些攔截器棧的action,則應該將它放置在其它的包下【如:test1】
攔截器與過濾器的區別:
1.攔截器是基於java反射機制的,而過濾器是基於函數回調的。
2.過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
3.攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
4.攔截器可以訪問Action上下文、值棧里的對象,而過濾器不能。
5.在Action的生命周期中,攔截器可以多次調用,而過濾器只能在容器初始化時被調用一次。
參考:http://blog.csdn.net/laner0515/article/details/27692673/
http://blog.csdn.net/qjyong/article/details/1824607