最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Struts2攔截器機(jī)制

 更新時(shí)間:2017年06月26日 10:53:07   作者:Single_YAM  
這篇文章主要介紹了詳解Struts2攔截器機(jī)制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

Struts2的核心在于它復(fù)雜的攔截器,幾乎70%的工作都是由攔截器完成的。比如我們之前用于將上傳的文件對應(yīng)于action實(shí)例中的三個(gè)屬性的fileUpload攔截器,還有用于將表單頁面的http請求參數(shù)設(shè)置成action中對應(yīng)的屬性的param攔截器等。總之,在整個(gè)Struts框架中攔截器的作用是相當(dāng)大的,本篇將從以下幾點(diǎn)詳細(xì)介紹下有關(guān)Struts攔截器的內(nèi)容:

  1. 攔截器在Struts中的作用
  2. 自定義攔截器實(shí)現(xiàn)類
  3. 配置攔截器(包含配置默認(rèn)攔截器)
  4. 引用攔截器
  5. 配置攔截指定方法的攔截器
  6. 攔截器的攔截順序

一、攔截器在Struts中的作用

在我們的web.xml中,我們配置了一個(gè)過濾器,實(shí)現(xiàn)將所有請求交付StrutsPrepareAndExecuteFilter類。一旦接受到任意action的請求,該類會創(chuàng)建和初始化一個(gè)ActionProxy實(shí)例,它代理了具體的action,在其中我們可以添加任意攔截器在execute方法執(zhí)行之前和之后做一些額外的操作,最終會調(diào)用該action實(shí)例的execute方法,為用戶返回視圖結(jié)果字符串,然后系統(tǒng)會根據(jù)該視圖結(jié)果字符串調(diào)取相應(yīng)的視圖頁面。下圖是攔截器和action之間的關(guān)系:

這是一種典型的AOP思想,當(dāng)我們在Struts.xml中定義一個(gè)包的時(shí)候,大部分情況下我們會繼承struts-default文件,所以雖然我們在自己的配置文件中并沒有手動配置任何的攔截器,但是我們創(chuàng)建的action卻被很多攔截器攔截處理,就是因?yàn)閟truts-default中配置的攔截器生效了。Struts中內(nèi)建了很多的攔截器,他們大多被配置在struts-default文件中,詳細(xì)的內(nèi)建攔截器的介紹可以參考官方API,接下來我們看如何自定義一個(gè)攔截器。

二、自定義攔截器實(shí)現(xiàn)類

想要實(shí)現(xiàn)自己的攔截器類只需要實(shí)現(xiàn) com.opensymphony.xwork2.interceptor.Interceptor.Interceptor 接口即可,該接口中有如下幾個(gè)方法:

 public abstract void destroy();
 
 public abstract void init();
 
 public abstract String intercept(ActionInvocation paramActionInvocation)
  throws Exception;

init 方法在執(zhí)行攔截方法之前回調(diào),主要用于初始化一些資源,destroy 與init 方法對應(yīng),在攔截器實(shí)例被銷毀之前回調(diào),主要用于釋放在init 方法中打開的資源。intercept 方法是我們的攔截方法,我們可以重寫該方法來完成對action實(shí)例的攔截,該方法具有一個(gè)ActionInvocation 類型的參數(shù),該參數(shù)內(nèi)部引用了具體的action實(shí)例對象(如果該action還有其他攔截器的話),我們可以調(diào)用該參數(shù)的invoke方法調(diào)用具體action實(shí)例的execute方法或者調(diào)用下一個(gè)攔截器,intercept方法返回一個(gè)String 類型的字符串代表了具體視圖頁面。下面看個(gè)具體的例子:

public class TestAction extends ActionSupport {

  public String execute(){
    System.out.println("執(zhí)行execute方法......");
    return SUCCESS;
  }
}
public class MyIntercept implements Interceptor {

  public void init() {}
  public void destroy() {}

  public String intercept(ActionInvocation action) throws Exception{
    System.out.println("攔截action開始.......");
    String result = action.invoke();
    System.out.println("攔截action結(jié)束.......");
    return result;
  }
}

省略了配置攔截器和TestAction 的代碼,下圖是上述程序運(yùn)行的結(jié)果截圖:

三、配置和引用攔截器

上述的示例定義了一個(gè)簡單的攔截器實(shí)現(xiàn)類,我們省略了在struts.xml中配置和引用該攔截器的代碼,本小節(jié)將詳細(xì)的介紹如何在struts.xml中定義和引用我們自定義實(shí)現(xiàn)的攔截器類。

從struts-default.xml中我們可以看出來,我們使用<interceptors>元素定義攔截器name和物理位置的配對,例如:

<interceptors>
  <interceptor name="test" class="MyPackage.TestAction"/>
  ......
  ......
</interceptors>

上述代碼定義了一個(gè)攔截器test,它對應(yīng)于具體的一個(gè)class。需要注意的是,定義攔截器的元素 interceptors 及其子元素必須被配置在某個(gè)package包下。

以上只是定義了一個(gè)攔截器和具體攔截器實(shí)現(xiàn)類之間的映射關(guān)系,但是想要實(shí)現(xiàn)對某個(gè)具體的action的攔截需要使用元素<interceptor-ref>根據(jù)name屬性值引用一個(gè)上述已經(jīng)定義了的攔截器。例如:

<action name="test" class="MyPackage.TestAction">
  <interceptor-ref name="test"/>
  <result name="success">/index.jsp</result>
  ......
  ......
</action>

正如上述代碼展示的一樣,該元素用于引用一個(gè)已經(jīng)定義好了的攔截器,并且該元素出現(xiàn)在具體的action內(nèi)部,表明了該action具有一個(gè)test攔截器。以上代碼實(shí)現(xiàn)了對單個(gè)攔截器的定義和引用,其實(shí)對于攔截器棧(一堆攔截器的組合)來說配置也是類似的。定義一個(gè)攔截器棧的代碼是如下的:

<interceptor-stack name="攔截器棧名">
  interceptor-ref name="攔截器一"/>
  interceptor-ref name="攔截器二"/>
  interceptor-ref name="攔截器三"/>
  .....
</interceptor-stack>

引用一個(gè)攔截器棧就沒什么區(qū)別了:

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

當(dāng)然我們也可以通過

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

配置默認(rèn)攔截器或者攔截器棧,如果該包下某個(gè)action沒有顯式指定攔截器,那么就會調(diào)用該默認(rèn)攔截器,否則如果顯式配置了攔截器,那么默認(rèn)攔截器將會失效。

四、為Action中指定方法配置攔截器

在默認(rèn)情況下,我們?yōu)閍ction配置了攔截器之后,該攔截器將會攔截該action中所有的方法,這有時(shí)候會給我們帶來麻煩,當(dāng)然struts為我們提供API用來針對具體的某個(gè)方法配置攔截器。這里涉及到一個(gè)抽象類:MethodFilterInterceptor。該類實(shí)際上實(shí)現(xiàn)了Interceptor并完成了一些默認(rèn)實(shí)現(xiàn),我們簡單看看其中的代碼:

public abstract class MethodFilterInterceptor
 extends AbstractInterceptor
{
//該set集合保存了該攔截器不需要攔截的所有方法
 protected Set<String> excludeMethods = Collections.emptySet();
 //該set集合保存了所有該攔截器需要攔截的方法
 protected Set<String> includeMethods = Collections.emptySet();
 //省略getter,setter方法
 
 //用于攔截action的入口
 public String intercept(ActionInvocation invocation)
  throws Exception
 {
  if (applyInterceptor(invocation)) {
   return doIntercept(invocation);
  }
  return invocation.invoke();
 }
 
 //判斷當(dāng)前需要調(diào)用的action處理邏輯方法是否需要被此攔截器攔截
 protected boolean applyInterceptor(ActionInvocation invocation)
 {
  String method = invocation.getProxy().getMethod();
  
  boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(this.excludeMethods, this.includeMethods, method);
  if ((this.log.isDebugEnabled()) && 
   (!applyMethod)) {
   this.log.debug("Skipping Interceptor... Method [" + method + "] found in exclude list.", new String[0]);
  }
  return applyMethod;
 }
 
 //這是需要我們重寫的方法,具體作用下文介紹
 protected abstract String doIntercept(ActionInvocation paramActionInvocation)
  throws Exception;
}

從上述代碼中可以看出,該抽象類實(shí)現(xiàn)了Interceptor接口并完成了基本的實(shí)現(xiàn)。除此之外,該類提供了兩個(gè)集合用于保存該攔截器需要攔截的所有方法和不需要攔截的所有方法,攔截器入口intercept中會首先判斷此次請求action實(shí)例中的邏輯處理方法是否需要被該攔截器攔截,如果需要被攔截,那么將會調(diào)用doIntercept我們自己實(shí)現(xiàn)的攔截器邏輯。否則直接調(diào)用invoke方法執(zhí)行處理邏輯。所以一般來說,我們只需要重寫doIntercept方法完成攔截器的核心處理即可。

當(dāng)然此處需要注意一點(diǎn)的是,用于判斷當(dāng)前請求的處理邏輯方法是否需要被該攔截器攔截的方法applyInterceptor是在intercept中進(jìn)行校驗(yàn)的,也就是說在執(zhí)行doIntercept方法之前excludeMethods和includeMethods的值應(yīng)當(dāng)是已經(jīng)初始化完畢了的。所以我們在doIntercept中再次為這兩個(gè)屬性賦值是沒用的,因?yàn)橐呀?jīng)完成了校驗(yàn)。一般我們在struts.xml中為這兩個(gè)屬性賦值,因?yàn)樵撆渲梦募窍缺患虞d的。下面我們看個(gè)實(shí)例:

//自定義一個(gè)攔截器
public class MyIntercept extends MethodFilterInterceptor {

  protected String doIntercept(ActionInvocation action)
      throws Exception{
    System.out.println("攔截開始......");
    String result = action.invoke();
    System.out.println("攔截結(jié)束......");
    return result;
  }
}
//引用該攔截器并指定不需要攔截的方法
<action name="test" class="MyPackage.TestAction">
  <interceptor-ref name="test">
        <param name="excludeMethods">execute</param>
  </interceptor-ref>
  <result name="success">/index.jsp</result>
</action>

下面我們看運(yùn)行的結(jié)果截圖:

顯然我們指明了該攔截器不用攔截方法execute,當(dāng)然結(jié)果顯示的也是如我們所愿。如果我們修改上述struts.xml中內(nèi)容:

<action name="test" class="MyPackage.TestAction">
  <interceptor-ref name="test">
    <param name="includeMethods">execute</param>
  </interceptor-ref>
  <result name="success">/index.jsp</result>
</action>

我們指定該execute方法是需要被攔截器攔截的,下面運(yùn)行的結(jié)果截圖:

當(dāng)然如果需要指定多個(gè)方法需要被攔截或者不用被攔截,可以使用英文逗號隔開這些方法,例如:

<param name="includeMethods">方法一,方法二,方法三</param>

最后還有一點(diǎn)是:如果一個(gè)方法既被放在了includeMethods中也被放在了excludeMethods中,那么框架將會選擇攔截該方法。

五、有關(guān)攔截器機(jī)制的其他一些細(xì)節(jié)

攔截器的執(zhí)行順序是按照引用攔截器的順序決定的,例如我們定義兩個(gè)攔截器:

<action name="test" class="MyPackage.TestAction">
  <interceptor-ref name="test"/>
  <interceptor-ref name="test2"/>
  <result name="success">/index.jsp</result>
</action>

也就是說第一個(gè)攔截器攔截action之后,會調(diào)用invoke方法,如果還有其他攔截器則會調(diào)用下一個(gè)攔截器,一層層嵌套,最后結(jié)束最外層的攔截器。

上述實(shí)例中我們使用param參數(shù)為攔截器類中的includeMethods屬性賦值,但是如果是一個(gè)攔截器棧中我們有該如何為其中某個(gè)具體的攔截器屬性賦值呢?

<interceptor-ref name="攔截器棧">
  <param name="攔截器一.屬性名">屬性值</param>
</interceptor-ref>

至此,我們簡單了解了有關(guān)struts2中攔截器器的相關(guān)知識,如需深刻理解還要在具體項(xiàng)目中體會,總結(jié)不到之處,望海涵!

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java五種方式實(shí)現(xiàn)多線程循環(huán)打印問題

    Java五種方式實(shí)現(xiàn)多線程循環(huán)打印問題

    本文主要介紹了Java五種方式實(shí)現(xiàn)多線程循環(huán)打印問題,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • MyBatis配置文件的寫法和簡單使用

    MyBatis配置文件的寫法和簡單使用

    MyBatis 是支持定制化 SQL、存儲過程以及高級映射的優(yōu)秀的持久層框架。這篇文章主要介紹了MyBatis配置文件的寫法和簡單使用,需要的朋友參考下
    2017-01-01
  • SpringBoot/Spring?AOP默認(rèn)動態(tài)代理方式實(shí)例詳解

    SpringBoot/Spring?AOP默認(rèn)動態(tài)代理方式實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于SpringBoot/Spring?AOP默認(rèn)動態(tài)代理方式的相關(guān)資料,Spring AOP是一款基于Java的AOP框架,其中默認(rèn)采用動態(tài)代理方式實(shí)現(xiàn)AOP功能,本文將詳細(xì)介紹動態(tài)代理的實(shí)現(xiàn)原理和使用方法,需要的朋友可以參考下
    2023-03-03
  • 淺談用java實(shí)現(xiàn)事件驅(qū)動機(jī)制

    淺談用java實(shí)現(xiàn)事件驅(qū)動機(jī)制

    這篇文章主要介紹了淺談用java實(shí)現(xiàn)事件驅(qū)動機(jī)制,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • java解析xml之sax解析xml示例分享

    java解析xml之sax解析xml示例分享

    SAX基于事件的解析,解析器在一次讀取XML文件中根據(jù)讀取的數(shù)據(jù)產(chǎn)生相應(yīng)的事件,由應(yīng)用程序?qū)崿F(xiàn)相應(yīng)的事件處理邏輯,即它是一種“推”的解析方式;這種解析方法速度快、占用內(nèi)存少,但是它需要應(yīng)用程序自己處理解析器的狀態(tài),實(shí)現(xiàn)起來會比較麻煩
    2014-01-01
  • Java實(shí)現(xiàn)圖片模糊效果詳解

    Java實(shí)現(xiàn)圖片模糊效果詳解

    圖片模糊是圖像處理中的一種常見效果,它通過平均周圍像素的顏色來使圖像變得模糊,下面我們來看看如何使用Swing庫實(shí)現(xiàn)圖片模糊效果吧
    2025-02-02
  • java實(shí)現(xiàn)gif動畫效果(java顯示動態(tài)圖片)

    java實(shí)現(xiàn)gif動畫效果(java顯示動態(tài)圖片)

    這篇文章主要介紹了java實(shí)現(xiàn)gif動畫效果示例(java顯示動態(tài)圖片),需要的朋友可以參考下
    2014-04-04
  • SpringBoot使用@valid進(jìn)行參數(shù)校驗(yàn)的流程步驟

    SpringBoot使用@valid進(jìn)行參數(shù)校驗(yàn)的流程步驟

    SpringBoot 提供了一種方便的方式來進(jìn)行參數(shù)校驗(yàn):使用 Hibernate Validator,Spring Boot 提供了一種方便的方式來進(jìn)行參數(shù)校驗(yàn):使用 Hibernate Validator,所以本文給大家介紹了SpringBoot使用@valid進(jìn)行參數(shù)校驗(yàn)的流程步驟,需要的朋友可以參考下
    2023-09-09
  • IDEA配置MAVEN本地倉庫的實(shí)現(xiàn)步驟

    IDEA配置MAVEN本地倉庫的實(shí)現(xiàn)步驟

    本文主要介紹了IDEA配置MAVEN本地倉庫的實(shí)現(xiàn)步驟,將詳細(xì)介紹如何配置Maven環(huán)境變量,Maven配置文件,可以輕松地設(shè)置和配置MAVEN本地倉庫,以便在IDEA中享受更高效的開發(fā)體驗(yàn)
    2023-08-08
  • Java求出任意數(shù)字的各個(gè)位數(shù)之和方式

    Java求出任意數(shù)字的各個(gè)位數(shù)之和方式

    這篇文章主要介紹了Java求出任意數(shù)字的各個(gè)位數(shù)之和方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論

平潭县| 红河县| 巫溪县| 航空| 灵丘县| 铁岭市| 盘锦市| 岳池县| 杨浦区| 平安县| 定结县| 全南县| 永善县| 盘锦市| 永善县| 卢龙县| 泗阳县| 那曲县| 奎屯市| 正宁县| 定兴县| 老河口市| 阜城县| 嵊州市| 富顺县| 大理市| 元朗区| 乌兰察布市| 麻城市| 噶尔县| 潮州市| 图片| 盈江县| 五指山市| 遵化市| 永清县| 彩票| 梅州市| 陇川县| 广昌县| 介休市|