posts - 60,comments - 71,trackbacks - 0

          1.    理解攔截器

          1.1.    什么是攔截器:

          攔截器,在AOPAspect-Oriented Programming)中用于在某個(gè)方法或字段被訪(fǎng)問(wèn)之前,進(jìn)行攔截然后在之前或之后加入某些操作。攔截是AOP的一種實(shí)現(xiàn)策略。

          Webwork的中文文檔的解釋為——攔截器是動(dòng)態(tài)攔截Action調(diào)用的對(duì)象。它提供了一種機(jī)制可以使開(kāi)發(fā)者可以定義在一個(gè)action執(zhí)行的前后執(zhí)行的代碼,也可以在一個(gè)action執(zhí)行前阻止其執(zhí)行。同時(shí)也是提供了一種可以提取action中可重用的部分的方式。

          談到攔截器,還有一個(gè)詞大家應(yīng)該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱(chēng)為攔截器棧Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序聯(lián)結(jié)成一條鏈。在訪(fǎng)問(wèn)被攔截的方法或字段時(shí),攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。

          1.2.    攔截器的實(shí)現(xiàn)原理:

          大部分時(shí)候,攔截器方法都是通過(guò)代理的方式來(lái)調(diào)用的。Struts 2的攔截器實(shí)現(xiàn)相對(duì)簡(jiǎn)單。當(dāng)請(qǐng)求到達(dá)Struts 2ServletDispatcher時(shí),Struts 2會(huì)查找配置文件,并根據(jù)其配置實(shí)例化相對(duì)的攔截器對(duì)象,然后串成一個(gè)列表(list),最后一個(gè)一個(gè)地調(diào)用列表中的攔截器。如下圖:

          2.    攔截器的配置

          Struts 2已經(jīng)為您提供豐富多樣的,功能齊全的攔截器實(shí)現(xiàn)。大家可以至struts2jar包內(nèi)的struts-default.xml查看關(guān)于默認(rèn)的攔截器與攔截器鏈的配置。

          Struts2XWork)提供的攔截器的功能說(shuō)明:

           

          攔截器

          名字

          說(shuō)明

          Alias Interceptor

          alias

          在不同請(qǐng)求之間將請(qǐng)求參數(shù)在不同名字件轉(zhuǎn)換,請(qǐng)求內(nèi)容不變

          Chaining Interceptor

          chain

          讓前一個(gè)Action的屬性可以被后一個(gè)Action訪(fǎng)問(wèn),現(xiàn)在和chain類(lèi)型的result<result type=”chain”>)結(jié)合使用。

          Checkbox Interceptor

          checkbox

          添加了checkbox自動(dòng)處理代碼,將沒(méi)有選中的checkbox的內(nèi)容設(shè)定為false,而html默認(rèn)情況下不提交沒(méi)有選中的checkbox。

          Cookies Interceptor

          cookies

          使用配置的name,value來(lái)是指cookies

          Conversion Error Interceptor

          conversionError

          將錯(cuò)誤從ActionContext中添加到Action的屬性字段中。

          Create Session Interceptor

          createSession

          自動(dòng)的創(chuàng)建HttpSession,用來(lái)為需要使用到HttpSession的攔截器服務(wù)。

          Debugging Interceptor

          debugging

          提供不同的調(diào)試用的頁(yè)面來(lái)展現(xiàn)內(nèi)部的數(shù)據(jù)狀況。

          Execute and Wait Interceptor

          execAndWait

          在后臺(tái)執(zhí)行Action,同時(shí)將用戶(hù)帶到一個(gè)中間的等待頁(yè)面。

          Exception Interceptor

          exception

          將異常定位到一個(gè)畫(huà)面

          File Upload Interceptor

          fileUpload

          提供文件上傳功能

          I18n Interceptor

          i18n

          記錄用戶(hù)選擇的locale

          Logger Interceptor

          logger

          輸出Action的名字

          Message Store Interceptor

          store

          存儲(chǔ)或者訪(fǎng)問(wèn)實(shí)現(xiàn)ValidationAware接口的Action類(lèi)出現(xiàn)的消息,錯(cuò)誤,字段錯(cuò)誤等。

          Model Driven Interceptor

          model-driven

          如果一個(gè)類(lèi)實(shí)現(xiàn)了ModelDriven,將getModel得到的結(jié)果放在Value Stack中。

          Scoped Model Driven

          scoped-model-driven

          如果一個(gè)Action實(shí)現(xiàn)了ScopedModelDriven,則這個(gè)攔截器會(huì)從相應(yīng)的Scope中取出model調(diào)用ActionsetModel方法將其放入Action內(nèi)部。

          Parameters Interceptor

          params

          將請(qǐng)求中的參數(shù)設(shè)置到Action中去。

          Prepare Interceptor

          prepare

          如果Acton實(shí)現(xiàn)了Preparable,則該攔截器調(diào)用Action類(lèi)的prepare方法。

          Scope Interceptor

          scope

          Action狀態(tài)存入sessionapplication的簡(jiǎn)單方法。

          Servlet Config Interceptor

          servletConfig

          提供訪(fǎng)問(wèn)HttpServletRequestHttpServletResponse的方法,以Map的方式訪(fǎng)問(wèn)。

          Static Parameters Interceptor

          staticParams

          struts.xml文件中將<action>中的<param>中的內(nèi)容設(shè)置到對(duì)應(yīng)的Action中。

          Roles Interceptor

          roles

          確定用戶(hù)是否具有JAAS指定的Role,否則不予執(zhí)行。

          Timer Interceptor

          timer

          輸出Action執(zhí)行的時(shí)間

          Token Interceptor

          token

          通過(guò)Token來(lái)避免雙擊

          Token Session Interceptor

          tokenSession

          Token Interceptor一樣,不過(guò)雙擊的時(shí)候把請(qǐng)求的數(shù)據(jù)存儲(chǔ)在Session

          Validation Interceptor

          validation

          使用action-validation.xml文件中定義的內(nèi)容校驗(yàn)提交的數(shù)據(jù)。

          Workflow Interceptor

          workflow

          調(diào)用Actionvalidate方法,一旦有錯(cuò)誤返回,重新定位到INPUT畫(huà)面

          Parameter Filter Interceptor

          N/A

          從參數(shù)列表中刪除不必要的參數(shù)

          Profiling Interceptor

          profiling

          通過(guò)參數(shù)激活profile

           

                 struts.xml文件中定義攔截器,攔截器棧:

          <package name="my" extends="struts-default" namespace="/manage">

                  <interceptors>

                  <!-- 定義攔截器 -->

                  <interceptor name="攔截器名" class="攔截器實(shí)現(xiàn)類(lèi)"/>

                  <!-- 定義攔截器棧 -->

                  <interceptor-stack name="攔截器棧名">

                       <interceptor-ref name="攔截器一"/>

                       <interceptor-ref name="攔截器二"/>

                  </interceptor-stack>

                  </interceptors>

                  ......

          </package>

          3.    使用攔截器

          一旦定義了攔截器和攔截器棧后,就可以使用這個(gè)攔截器或攔截器棧來(lái)攔截Action了。攔截器的攔截行為將會(huì)在Actionexceute方法執(zhí)行之前被執(zhí)行。

          <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">

                      <result name="success">/success.jsp</result>

                      <result name="error">/error.jsp</result>

          <!-- 使用攔截器,一般配置在result之后, -->

          <!-- 引用系統(tǒng)默認(rèn)的攔截器 -->

          <interceptor-ref name="defaultStack"/>

                      <interceptor-ref name="攔截器名或攔截器棧名"/>

                  </action>

                 此處需要注意的是,如果為Action指定了一個(gè)攔截器,則系統(tǒng)默認(rèn)的攔截器棧將會(huì)失去作用。為了繼續(xù)使用默認(rèn)攔截器,所以上面配置文件中手動(dòng)引入了默認(rèn)攔截器。

          4.    自定義攔截器

          作為“框架(framework)”,可擴(kuò)展性是不可或缺的。雖然,Struts 2為我們提供如此豐富的攔截器實(shí)現(xiàn),但是這并不意味我們失去創(chuàng)建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當(dāng)容易的一件事。

          4.1.    實(shí)現(xiàn)攔截器類(lèi):

          所有的Struts 2的攔截器都直接或間接實(shí)現(xiàn)接口com.opensymphony.xwork2.interceptor.Interceptor。該接口提供了三個(gè)方法:

          1)      void init(); 在該攔截器被初始化之后,在該攔截器執(zhí)行攔截之前,系統(tǒng)回調(diào)該方法。對(duì)于每個(gè)攔截器而言,此方法只執(zhí)行一次。

          2)      void destroy();該方法跟init()方法對(duì)應(yīng)。在攔截器實(shí)例被銷(xiāo)毀之前,系統(tǒng)將回調(diào)該方法。

          3)      String intercept(ActionInvocation invocation) throws Exception; 該方法是用戶(hù)需要實(shí)現(xiàn)的攔截動(dòng)作。該方法會(huì)返回一個(gè)字符串作為邏輯視圖。

          除此之外,繼承類(lèi)com.opensymphony.xwork2.interceptor.AbstractInterceptor是更簡(jiǎn)單的一種實(shí)現(xiàn)攔截器類(lèi)的方式,因?yàn)榇祟?lèi)提供了init()destroy()方法的空實(shí)現(xiàn),這樣我們只需要實(shí)現(xiàn)intercept方法。

          4.2.    使用自定義攔截器:

          兩個(gè)步驟:

          l 通過(guò)<interceptor …>元素來(lái)定義攔截器。

          l 通過(guò)<interceptor-ref …>元素來(lái)使用攔截器。

          5.    自定義攔截器示例

          5.1.    問(wèn)題描述:

          使用自定義攔截器來(lái)完成用戶(hù)權(quán)限的控制:當(dāng)瀏覽者需要請(qǐng)求執(zhí)行某個(gè)操作時(shí),應(yīng)用需要先檢查瀏覽者是否登錄,以及是否有足夠的權(quán)限來(lái)執(zhí)行該操作。

          5.2.    實(shí)現(xiàn)權(quán)限控制攔截器類(lèi):

          AuthorizationInterceptor.java

          package org.qiujy.common;

          import java.util.Map;

          import com.opensymphony.xwork2.Action;

          import com.opensymphony.xwork2.ActionInvocation;

          import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

          /**

           *權(quán)限檢查攔截器

           *

           *@authorqiujy

           *@version1.0

           */

          publicclass AuthorizationInterceptor extends AbstractInterceptor {

              /*

               * 攔截Action處理的攔截方法

               *

               */

              public String intercept(ActionInvocation invocation) throws Exception {

                 

                  Map session = invocation.getInvocationContext().getSession();

                  String userName = (String) session.get("userName");

                 

                  if (null != userName && userName.equals("test")) {

                      System.out.println("攔截器:合法用戶(hù)登錄---");

                      return invocation.invoke();

                  } else {

                      System.out.println("攔截器:用戶(hù)未登錄---");

                      return Action.LOGIN;

                  }

              }

          }

           

          5.3.    配置權(quán)限控制攔截器:

          struts.xml

          <!DOCTYPE struts PUBLIC

                  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

                  "http://struts.apache.org/dtds/struts-2.0.dtd">

          <struts>

              <package name="my" extends="struts-default">

                 

                  <interceptors>

                  <!-- 定義權(quán)限控制攔截器 -->

                  <interceptor name="authority" class="org.qiujy.common.AuthorizationInterceptor"/>

                  </interceptors>

                 

                  <!-- 定義全局處理結(jié)果 -->

                 <global-results>

                  <!-- 邏輯名為login的結(jié)果,映射到/login.jsp頁(yè)面 -->

                  <result name="login">/login.jsp</result>

                  </global-results>

                 

                  <action name="listall" class="org.qiujy.web.struts2.action.UserAction" method="listAllUser">

                      <result name="success">/listall.jsp</result>

                      <!-- 使用攔截器 -->

                      <interceptor-ref name="defaultStack"/>

                      <interceptor-ref name="authority"/>

                  </action>

                 

                  <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">

                      <result name="success">/success.jsp</result>

                  </action>

              </package>

          </struts>

                 其它頁(yè)面見(jiàn)源代碼。

          5.4.    運(yùn)行調(diào)試:

          在瀏覽器地址欄直接輸入http://localhost:8080/AuthorityInterceptorDemo/listall.action來(lái)訪(fǎng)問(wèn),此動(dòng)作配置了權(quán)限攔截器,所有被轉(zhuǎn)到登錄頁(yè)面。

          登錄后:

          再訪(fǎng)問(wèn)http://localhost:8080/AuthorityInterceptorDemo/listall.action這個(gè)鏈接:

          如果為了簡(jiǎn)化struts.xml文件的配置,避免在每個(gè)Action重復(fù)配置該攔截器,可以將攔截器配置成了一個(gè)默認(rèn)攔截器棧。如下:

          <!DOCTYPE struts PUBLIC

                  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

                  "http://struts.apache.org/dtds/struts-2.0.dtd">

          <struts>

              <package name="my" extends="struts-default">

                  <interceptors>

                      <!-- 定義權(quán)限控制攔截器 -->

                      <interceptor name="authority"

                          class="org.qiujy.common.AuthorizationInterceptor" />

                      <!-- 定義一個(gè)包含權(quán)限控制的攔截器棧 -->

                      <interceptor-stack name="mydefault">

                          <interceptor-ref name="defaultStack" />

                          <interceptor-ref name="authority" />

                      </interceptor-stack>

                  </interceptors>

                 

                  <!-- 定義默認(rèn)攔截器 -->

                  <default-interceptor-ref name="mydefault" />

                  <!-- 定義全局處理結(jié)果 -->

                  <global-results>

                      <!-- 邏輯名為login的結(jié)果,映射到/login.jsp頁(yè)面 -->

                      <result name="login">/login.jsp</result>

                  </global-results>

                  <action name="listall"

                      class="org.qiujy.web.struts2.action.UserAction"

                      method="listAllUser">

                      <result name="success">/listall.jsp</result>

                  </action>

              </package>

             

              <package name="font" extends="struts-default">

                  <action name="userOpt" class="org.qiujy.web.struts2.action.UserAction">

                      <result name="success">/success.jsp</result>

                  </action>

              </package>

          </struts>

          一旦在某個(gè)包下定義了默認(rèn)攔截器棧,在該包下的所有action都會(huì)使用此攔截器棧。對(duì)于那些不想使用些攔截器棧的action,則應(yīng)該將它放置在其它的包下。

          posted on 2008-06-16 10:48 henry1451 閱讀(527) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 開(kāi)源技術(shù)
          主站蜘蛛池模板: 马尔康县| 东城区| 嘉定区| 铜梁县| 庐江县| 平湖市| 阿克苏市| 会东县| 莎车县| 新竹市| 招远市| 蒙阴县| 灌云县| 镇江市| 天津市| 中牟县| 仙游县| 涿州市| 那曲县| 崇仁县| 香河县| 黑河市| 囊谦县| 南江县| 金山区| 镇远县| 涞水县| 晋江市| 惠来县| 肃南| 建平县| 鄢陵县| 长顺县| 石嘴山市| 平湖市| 伊金霍洛旗| 延边| 林甸县| 启东市| 闻喜县| 海原县|