<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Java Study Center  
    日歷
    <2008年9月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011
    統(tǒng)計
    • 隨筆 - 40
    • 文章 - 3
    • 評論 - 0
    • 引用 - 0

    導航

    常用鏈接

    留言簿(1)

    隨筆檔案(40)

    文章檔案(3)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

     

    首先,要跟大家道個歉,前一陣子為給客戶個一個DEMO,忙得不可開交,所以很久沒有更新Blog。提到這個DEMO我想順便跟大家分享一下心得——如果大家希望快速開發(fā),一個類似Struts 2這樣的簡單方便的WEB框架必不可少。我們在開發(fā)DEMO使用的還是Struts 1.2.8,而且沒有不使用任何EL(表達式語言),導致頁面出現(xiàn)無數(shù)類似“<%= ((Integer) request.getAttribute("xx")).intValue()%6 %>”的代碼。Struts 1.x的Form Bean的麻煩使得有部分同事直接使用request.getParameter(String arg),繼而引入另一種麻煩。諸如此類的問題,在DEMO這樣時間緊迫的項目凸顯了Struts 1.x對快速開發(fā)的無能為力。不過沒辦法,由于我們項目中的幾個資深員工除了Struts 1.x外,對其它的WEB框架似乎不大感興趣。

    言歸正傳,Interceptor(以下譯為攔截器)是Struts 2的一個強有力的工具,有許多功能(feature)都是構(gòu)建于它之上,如國際化、轉(zhuǎn)換器校驗等。

    什么是攔截器

    攔截器,在AOP(Aspect-Oriented Programming)中用于在某個方法或字段被訪問之前,進行攔截然后在之前或之后加入某些操作。攔截是AOP的一種實現(xiàn)策略。

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

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

    實現(xiàn)原理

    Struts 2的攔截器實現(xiàn)相對簡單。當請求到達Struts 2的ServletDispatcher時,Struts 2會查找配置文件,并根據(jù)其配置實例化相對的攔截器對象,然后串成一個列表(list),最后一個一個地調(diào)用列表中的攔截器,如圖1所示。

    圖1 攔截器調(diào)用序列圖
    圖1 攔截器調(diào)用序列圖

    已有的攔截器

    Struts 2已經(jīng)為您提供豐富多樣的,功能齊全的攔截器實現(xiàn)。大家可以到struts2-all-2.0.1.jar或struts2-core-2.0.1.jar包的struts-default.xml查看關(guān)于默認的攔截器與攔截器鏈的配置。

    在本文使用是Struts 2的最新發(fā)布版本2.0.1。需要下載的朋友請點擊以下鏈接:
    http://apache.justdn.org/struts/binaries/struts-2.0.1-all.zip

    以下部分就是從struts-default.xml文件摘取的內(nèi)容:

    < interceptor name ="alias" class ="com.opensymphony.xwork2.interceptor.AliasInterceptor" />
    < interceptor name ="autowiring" class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" />
    < interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" />
    < interceptor name ="conversionError" class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" />
    < interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" />
    < interceptor name ="debugging" class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
    < interceptor name ="external-ref" class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" />
    < interceptor name ="execAndWait" class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" />
    < interceptor name ="exception" class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" />
    < interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" />
    < interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" />
    < interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" />
    < interceptor name ="model-driven" class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" />
    < interceptor name ="scoped-model-driven" class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" />
    < interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
    < interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" />
    < interceptor name ="static-params" class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" />
    < interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" />
    < interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" />
    < interceptor name ="sessionAutowiring" class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" />
    < interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" />
    < interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" />
    < interceptor name ="token-session" class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
    < interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" />
    < interceptor name ="workflow" class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" />
    < interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" />
    < interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" />
    < interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />

    配置和使用攔截器

    在struts-default.xml中已經(jīng)配置了以上的攔截器。如果您想要使用上述攔截器,只需要在應用程序struts.xml文件中通過“<include file="struts-default.xml" />”將struts-default.xml文件包含進來,并繼承其中的struts-default包(package),最后在定義Action時,使用“<interceptor-ref name="xx" />”引用攔截器或攔截器棧(interceptor stack)。一旦您繼承了struts-default包(package),所有Action都會調(diào)用攔截器棧 ——defaultStack。當然,在Action配置中加入“<interceptor-ref name="xx" />”可以覆蓋defaultStack。

    下面是關(guān)于攔截器timer使用的例子。首先,新建Action類tuotrial/TimerInterceptorAction.java,內(nèi)容如下:

    package tutorial;

    import com.opensymphony.xwork2.ActionSupport;

    public class TimerInterceptorAction extends ActionSupport {
       @Override
       
    public String execute() {
           
    try {
               
    // 模擬耗時的操作
               Thread.sleep( 500 );
           }
    catch (Exception e) {
               e.printStackTrace();
           }

           
    return SUCCESS;
       }

    }

    配置Action,名為Timer,配置文件如下:

    <! DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
            "http://struts.apache.org/dtds/struts-2.0.dtd"
    >
    < struts >
       
    < include file ="struts-default.xml" />    
       
    < package name ="InterceptorDemo" extends ="struts-default" >
           
    < action name ="Timer" class ="tutorial.TimerInterceptorAction" >
               
    < interceptor-ref name ="timer" />
               
    < result > /Timer.jsp </ result >
           
    </ action >
       
    </ package >
    </ struts >

    至于Timer.jsp可以隨意寫些什么到里面。發(fā)布運行應用程序,在瀏覽器的地址欄鍵入http://localhost:8080/Struts2_Interceptor/Timer.action,在出現(xiàn)Timer.jsp頁面后,查看服務器的后臺輸出。

    2006 - 12 - 6 14 : 27 : 32 com.opensymphony.xwork2.interceptor.TimerInterceptor doLog
    信息: Executed action
    [ //Timer!execute ] took 2859 ms.

    在您的環(huán)境中執(zhí)行Timer!execute的耗時,可能上述的時間有些不同,這取決于您PC的性能。但是無論如何,2859 ms與500 ms還是相差太遠了。這是什么原因呢?其實原因是第一次加載Timer時,需要進行一定的初始工作。當你重新請求Timer.action時,以上輸出會變?yōu)椋?/p>

    2006 - 12 - 6 14 : 29 : 18 com.opensymphony.xwork2.interceptor.TimerInterceptor doLog
    信息: Executed action
    [ //Timer!execute ] took 500 ms.

    OK,這正是我們期待的結(jié)果。上述例子演示了攔截器timer的用途——用于顯示執(zhí)行某個action方法的耗時,在我們做一個粗略的性能調(diào)試時,這相當有用。

    自定義攔截器

    作為“框架(framework)”,可擴展性是不可或缺的,因為世上沒有放之四海而皆準的東西。雖然,Struts 2為我們提供如此豐富的攔截器實現(xiàn),但是這并不意味我們失去創(chuàng)建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當容易的一件事。

     

    大家在開始著手創(chuàng)建自定義攔截器前,切記以下原則:
    攔截器必須是無狀態(tài)的,不要使用在API提供的ActionInvocation之外的任何東西。

    要求攔截器是無狀態(tài)的原因是Struts 2不能保證為每一個請求或者action創(chuàng)建一個實例,所以如果攔截器帶有狀態(tài),會引發(fā)并發(fā)問題。

    所有的Struts 2的攔截器都直接或間接實現(xiàn)接口com.opensymphony.xwork2.interceptor.Interceptor。除此之外,大家可能更喜歡繼承類com.opensymphony.xwork2.interceptor.AbstractInterceptor。

    以下例子演示通過繼承AbstractInterceptor,實現(xiàn)授權(quán)攔截器。

    首先,創(chuàng)建授權(quán)攔截器類tutorial.AuthorizationInterceptor,代碼如下:

    package tutorial;

    import java.util.Map;

    import com.opensymphony.xwork2.Action;
    import com.opensymphony.xwork2.ActionInvocation;
    import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

    public class AuthorizationInterceptor extends AbstractInterceptor {

       @Override
       
    public String intercept(ActionInvocation ai) throws Exception {
           Map session
    = ai.getInvocationContext().getSession();
           String role
    = (String) session.get( " ROLE " );
           
    if ( null != role) {
               Object o
    = ai.getAction();
               
    if (o instanceof RoleAware) {
                   RoleAware action
    = (RoleAware) o;
                   action.setRole(role);
               }

               
    return ai.invoke();
           }
    else {
               
    return Action.LOGIN;
           }
           
       }


    }

    以上代碼相當簡單,我們通過檢查session是否存在鍵為“ROLE”的字符串,判斷用戶是否登陸。如果用戶已經(jīng)登陸,將角色放到Action中,調(diào)用Action;否則,攔截直接返回Action.LOGIN字段。為了方便將角色放入Action,我定義了接口tutorial.RoleAware,代碼如下:

    package tutorial;

    public interface RoleAware {
       
    void setRole(String role);
    }

    接著,創(chuàng)建Action類tutorial.AuthorizatedAccess模擬訪問受限資源,它作用就是通過實現(xiàn)RoleAware獲取角色,并將其顯示到ShowUser.jsp中,代碼如下:

    package tutorial;

    import com.opensymphony.xwork2.ActionSupport;

    public class AuthorizatedAccess extends ActionSupport implements RoleAware {
       
    private String role;
       
       
    public void setRole(String role) {
           
    this .role = role;
       }

       
       
    public String getRole() {
           
    return role;
       }


       @Override
       
    public String execute() {
           
    return SUCCESS;
       }

    }

    以下是ShowUser.jsp的代碼:

    <% @ page  contentType = " text/html; charset=UTF-8 " %>
    <% @taglib prefix = " s " uri = " /struts-tags " %>
    < html >
    < head >
       
    < title > Authorizated User </ title >
    </ head >
    < body >
       
    < h1 > Your role is: < s:property value ="role" /></ h1 >
    </ body >
    </ html >

    然后,創(chuàng)建tutorial.Roles初始化角色列表,代碼如下:

    package tutorial;

    import java.util.Hashtable;
    import java.util.Map;


    public class Roles {
       
    public Map < String, String > getRoles() {
           Map
    < String, String > roles = new Hashtable < String, String > ( 2 );
           roles.put(
    " EMPLOYEE " , " Employee " );
           roles.put(
    " MANAGER " , " Manager " );
           
    return roles;
       }

    }

    接下來,新建Login.jsp實例化tutorial.Roles,并將其roles屬性賦予<s:radio>標志,代碼如下:

    <% @ page  contentType = " text/html; charset=UTF-8 " %>
    <% @taglib prefix = " s " uri = " /struts-tags " %>
    < html >
    < head >
       
    < title > Login </ title >
    </ head >
    < body >
       
    < h1 > Login </ h1 >
        Please select a role below:
       
    < s:bean id ="roles" name ="tutorial.Roles" />
       
    < s:form action ="Login" >
           
    < s:radio list ="#roles.roles" value ="'EMPLOYEE'" name ="role" label ="Role" />
           
    < s:submit />
       
    </ s:form >
    </ body >
    </ html >

    創(chuàng)建Action類tutorial.Login將role放到session中,并轉(zhuǎn)到Action類tutorial.AuthorizatedAccess,代碼如下:

    package tutorial;

    import java.util.Map;

    import org.apache.struts2.interceptor.SessionAware;

    import com.opensymphony.xwork2.ActionSupport;

    public class Login extends ActionSupport implements SessionAware {
       
    private String role;    
       
    private Map session;

       
    public String getRole() {
           
    return role;
       }


       
    public void setRole(String role) {
           
    this .role = role;
       }

       
       
    public void setSession(Map session) {
           
    this .session = session;
       }


       @Override
       
    public String execute() {
           session.put(
    " ROLE " , role);
           
    return SUCCESS;
       }
       
    }

    最后,配置struts.xml文件,內(nèi)容如下:

    <! DOCTYPE struts PUBLIC
            "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
            "http://struts.apache.org/dtds/struts-2.0.dtd"
    >
    < struts >
       
    < include file ="struts-default.xml" />    
       
    < package name ="InterceptorDemo" extends ="struts-default" >
           
    < interceptors >
               
    < interceptor name ="auth" class ="tutorial.AuthorizationInterceptor" />
           
    </ interceptors >
           
    < action name ="Timer" class ="tutorial.TimerInterceptorAction" >
               
    < interceptor-ref name ="timer" />
               
    < result > /Timer.jsp </ result >
           
    </ action >
           
    < action name ="Login" class ="tutorial.Login" >
               
    < result type ="chain" > AuthorizatedAccess </ result >
           
    </ action >
           
    < action name ="AuthorizatedAccess" class ="tutorial.AuthorizatedAccess" >
               
    < interceptor-ref name ="auth" />
               
    < result name ="login" > /Login.jsp </ result >
               
    < result name ="success" > /ShowRole.jsp </ result >
           
    </ action >
       
    </ package >
    </ struts >

    發(fā)布運行應用程序,在瀏覽器地址欄中輸入:http://localhost:8080/Struts2_Interceptor/AuthorizatedAccess.action。由于此時,session還沒有鍵為“ROLE”的值,所以返回Login.jsp頁面,如圖2所示:

    圖2 Login.jsp
    圖2 Login.jsp

    選中Employee,點擊Submit,出現(xiàn)圖3所示頁面:

    圖3 ShowRole.jsp
    圖3 ShowRole.jsp

    總結(jié)

    攔截器是Struts 2比較重要的一個功能。通過正確地使用攔截器,我們可以編寫高可復用的代碼。

    posted on 2008-09-17 15:34 綠茶_鄭州 閱讀(85) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
     
    Copyright © 綠茶_鄭州 Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 亚洲综合激情九月婷婷| 免费手机在线看片| 国产成人精品123区免费视频| 暖暖免费中文在线日本| 亚洲国产精品一区二区久久| 国产精品视频永久免费播放| 国产精品小视频免费无限app | 亚洲图片中文字幕| 免费观看四虎精品国产永久| 久久香蕉国产线看免费| 亚洲av乱码中文一区二区三区| 亚洲AV无码国产精品麻豆天美| 麻豆国产入口在线观看免费| 日本不卡免费新一区二区三区| 亚洲区日韩精品中文字幕| 亚洲欧洲第一a在线观看| 免费久久精品国产片香蕉| 在免费jizzjizz在线播| 一级做a爰片久久免费| 亚洲字幕AV一区二区三区四区 | 亚洲国产精品无码观看久久| 亚洲av综合avav中文| 全部免费毛片在线| 久久久久久精品免费免费自慰| ssswww日本免费网站片| 亚洲一区二区三区免费在线观看| 伊人久久大香线蕉亚洲| 女人18毛片a级毛片免费| 精品久久8x国产免费观看| 三上悠亚电影全集免费| 另类专区另类专区亚洲| 精品丝袜国产自在线拍亚洲| 亚洲男人第一av网站| 亚洲午夜福利在线观看| 亚洲 无码 在线 专区| 成人免费视频88| 免费看污成人午夜网站| 久久精品一本到99热免费| 天黑黑影院在线观看视频高清免费| 国产精品久久久久久亚洲小说| 亚洲国产最大av|