Struts2.0——什麼是攔截器

一、什麼是攔截器?

提 到攔截器,使我不得不想起武俠劇中劫匪們常說的一句話:“此山是我開,此樹是我栽,要打此路過,留下買路財!”。難不成程序中也有“打劫”的,說的沒錯, 攔截器就是個打劫的。在現實生活中,劫匪劫的大都是錢財,當然也有別的什麼,那麼程序中的“劫匪”劫的又是什麼呢?或者說程序中爲什麼需要它?在我們的日 常編程中少不了寫一些重複的代碼,例如在一個地方中寫了一段代碼,後來發現這段代碼在其它地方中同樣需要,在傳統的編程中我們一定會採取複製、粘貼的辦 法。如果這段代碼只在這一兩個處需要,我們採取這種辦法,還說的過去,但是如果系統對這段代碼過於依賴,也就是這段代碼在系統中出現的過多,如果那一天我 們發現這段代碼中在某些地方還需要完善,我們是不是要着個修改它們呢?我估計沒有人會這麼做,它嚴重違反了軟件開發中一條非常重要的DRY規則,不寫重複代碼。說了這麼多你一定知道我們爲什麼需要在程序中弄一個“劫匪”了吧。這個“劫匪”就是並不是劫取什麼東西,只是爲了在某個程序執行前後,動態的增加一些功能(以前所寫通用代碼塊)或進行一些檢查工作。那麼這個攔截器到底是怎麼實現的呢?實際上它是用Java中的動態代理來實現的,具體可以參考設計模式學習筆記(十六)—Proxy模式》。

二、攔截器在Struts2中的應用

對於Struts2框架而言,正是大量的內置攔截器完成了大部分操作。像params攔截器將http請求中參數解析出來賦值給Action中對應的屬性。Servlet-config攔截器負責把請求中HttpServletRequest實例和HttpServletResponse實例傳遞給Action……struts2內置的攔截器有很多,在此我就不一一列舉了,具體可以參考《Struts2中有關struts-default.xml,struts.xml,struts.properties文件詳解》。

那麼怎麼在struts2中定義自己的攔截器呢?

很簡單Struts2爲我們提供了一個Interceptor接口,該接口源代碼如下:

publicinterface Interceptor extends Serializable {

    void destroy();

    void init();

    String intercept(ActionInvocation invocation) throws Exception;

}

1)    init():在攔截器執行之前調用,主要用於初始化系統資源。

2)    destroty():init()對應,用於攔截器執行之後銷燬資源。

3)    intercept():攔截器的核心方法,實現具體的攔截操作。與action一樣,該方法也返回一個字符串作爲邏輯視圖。如果攔截器成功調用了action,則返回一個真正的,也就是該actionexecute()方法返回的邏輯視圖,反之,則返回一個自定義的邏輯視圖。

通常我們使用攔截器並不需要申請資源,爲此Struts2還爲我們提供了一個AbstractInterceptor類,該類的init()destroy()都是空實現。我們開發自己的攔截器只需要繼承這個類就行了。

下面創建一個判斷用戶是否登錄的攔截器。代碼如下:

struts.xml中配置一下。

ExpandedBlockStart.gif/** *//**
InBlock.gif *
InBlock.gif *
@author <a href="mailto:[email protected]">flustar</a>
InBlock.gif *
@version 1.0
InBlock.gif * Creation date: Feb 12, 2008 5:05:28 PM
ExpandedBlockEnd.gif
*/

None.gif
None.gif
import java.util.Map;
None.gif
import com.opensymphony.xwork2.Action;
None.gif
import com.opensymphony.xwork2.ActionInvocation;
None.gif
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
None.gif
None.gif@SuppressWarnings(
"serial")
ExpandedBlockStart.gif
public class CheckLoginInterceptor extends AbstractInterceptor dot.gif{
InBlock.gif
InBlock.gif     @SuppressWarnings(
"unchecked")
ExpandedSubBlockStart.gif    
public String intercept(ActionInvocation actionInvocation) throws Exception dot.gif{
InBlock.gif          System.out.println(
"begin check login interceptor!");
InBlock.gif
InBlock.gif            
// 檢查Session中是否存在user
InBlock.gif

InBlock.gif             Map session
= actionInvocation.getInvocationContext().getSession();
InBlock.gif
InBlock.gif             String username
= (String) session.get("user");
InBlock.gif
ExpandedSubBlockStart.gif            
if (username != null && username.length() > 0) dot.gif{
InBlock.gif
InBlock.gif                
// 存在的情況下進行後續操作。
InBlock.gif

InBlock.gif                 System.out.println(
"already login!");
InBlock.gif
InBlock.gif                
return actionInvocation.invoke();
InBlock.gif
ExpandedSubBlockStart.gif             }
else dot.gif{
InBlock.gif
InBlock.gif                
// 否則終止後續操作,返回LOGIN
InBlock.gif

InBlock.gif                 System.out.println(
"no login, forward login page!");
InBlock.gif
InBlock.gif                
return Action.LOGIN;
InBlock.gif
ExpandedSubBlockEnd.gif             }

InBlock.gif
ExpandedSubBlockEnd.gif         }

InBlock.gif
InBlock.gif
ExpandedBlockEnd.gif     }

None.gif
None.gif


創建好攔截器後,還不能使用,還需要我們在

下面看一下怎麼配置攔截器。

<interceptors>

           <interceptor name="checkLogin" class="com.myblog.interceptor.CheckLoginInterceptor" />

</interceptors>

這個定義好的攔截器在Action中怎麼使用呢?使用方法很簡單,如下:

<action name=" " class=" " >

           <result> </result>

           <interceptor-ref name="checkLogin" />

</action>

一旦我們爲某個action引用了自定義的攔截器,struts2默認的攔截器就不會再起作用,因此還需要引用默認攔截器。

<action name=" " class=" " >

           <result> </result>

           <interceptor-ref name="checkLogin" />

                     <interceptor-ref name="defaultStack" />

</action>

但是我們這麼做似乎也不太方便,因爲如果攔截器checkLogin需要被多個action引用的話,每一個都要配置一遍太麻煩了。我們可以把它定義成默認的攔截器。

<interceptors>

           <interceptor name="checkLogin" class="com.myblog.interceptor.CheckLoginInterceptor" />

           <!—-定義一個攔截器棧-->

           <interceptor-stack name="mydefault">

              <interceptor-ref name="defaultStack" />

              <interceptor-ref name="checkLogin" />

           </interceptor-stack>

</interceptors>

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

另外,struts2還爲我們提供了一個方法過濾的攔截器MethodFilterInterceptor類,該類繼承AbstractInterceptor類,重寫了intercept(ActionInvocation invocation)並提供了一個新的方法doInterceptor(ActionInvocation invocation)抽象方法。該類的使用方法很簡單,就不舉例了。這個攔截器與以往的攔截器配置有所不同。那就是可以指定哪些方法需要被攔截,那些不需要。通常在引用該攔截器時指定。

<interceptor-ref name=" ">

       <param name="exculdeMethods"></param>

       <param name="includeMethods"></param>    

</interceptor-ref>

exculdeMethods:是不被攔截的方法,如果有多個以逗號分隔。

includeMethods:需要被攔截的方法,如果有多個以逗號分隔。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章