struts2 詳解


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 已經為您提供豐富多樣的,功能齊全的攔截器實現。在struts2jar包內的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調用ActionsetModel方法將其放入Action內部。

Parameters Interceptor

params

將請求中的參數設置到Action中去。

Prepare Interceptor

prepare

如果Acton實現了Preparable,則該攔截器調用Action類的prepare方法。

Scope Interceptor

scope

Action狀態存入sessionapplication的簡單方法。

Servlet Config Interceptor

servletConfig

提供訪問HttpServletRequestHttpServletResponse的方法,以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

調用Actionvalidate方法,一旦有錯誤返回,重新定位到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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM