Vincent

          Vicent's blog
          隨筆 - 74, 文章 - 0, 評(píng)論 - 5, 引用 - 0
          數(shù)據(jù)加載中……

          WebWork教程- Interceptor(攔截器)

          Interceptor (攔截器)將 Action 共用的行為獨(dú)立出來,在 Action 執(zhí)行前后運(yùn)行。這也就是我們所說的 AOP Aspect Oriented Programming ,面向切面編程),它是分散關(guān)注的編程方法,它將通用需求功能從不相關(guān)類之中分離出來;同時(shí),能夠使得很多類共享一個(gè)行為,一旦行為發(fā)生變化,不必修改很多類,只要修改這個(gè)行為就可以。
          ?
          Interceptor 將很多功能從我們的 Action 中獨(dú)立出來,大量減少了我們 Action 的代碼,獨(dú)立出來的行為具有很好的重用性。 XWork 、 WebWork 的許多功能都是有 Interceptor 實(shí)現(xiàn),可以在配置文件中組裝 Action 用到的 Interceptor ,它會(huì)按照你指定的順序,在 Action 執(zhí)行前后運(yùn)行。 Interceptor 在框架中的應(yīng)用如下圖所示
          ?
          ?
          當(dāng)你提交對(duì) Aciton (默認(rèn)是 .action 結(jié)尾的 Url )的請(qǐng)求時(shí), ServletDispatcher 會(huì)根據(jù)你的請(qǐng)求,去調(diào)度并執(zhí)行相應(yīng)的 Action 。在 Action 執(zhí)行之前,調(diào)用被 Interceptor 截取, Interceptor Action 執(zhí)行前后運(yùn)行。
          ?
          我們?cè)谟脩糇?cè)的例子中就使用了取得 Request 請(qǐng)求參數(shù)的攔截器,配置文件中 <interceptor-ref name="params"/> 將攔截器 params 組裝到 RegisterAction 中?!?/span> params ”在我們的 webwork-default.xml 配置文件中有定義, webwork-default.xml 中攔截器的定義如下:
          ?
          <interceptors>
          ??????????? <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
          ??????????? <interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/>
          ??????????? <interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/>
          ??????????? <interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/>
          ??????????? <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
          ??????????? <interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/>
          ??????????? <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
          ??????????? <interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/>
          ??????????? <interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/>
          ??????????? <interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/>
          ??????????? <interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/>
          ??????????? <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/>
          ??????????? <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/>
          ??????????? <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/>
          ??????????? <interceptor-stack name="defaultStack">
          ??????????????? <interceptor-ref name="static-params"/>
          ??????????????? <interceptor-ref name="params"/>
          ??????????????? <interceptor-ref name="conversionError"/>
          ??????????? </interceptor-stack>
          ??????????? <interceptor-stack name="validationWorkflowStack">
          ??????????????? <interceptor-ref name="defaultStack"/>
          ??????????????? <interceptor-ref name="validation"/>
          ??????????????? <interceptor-ref name="workflow"/>
          ??????????? </interceptor-stack>
          ??????? </interceptors>
          這些都時(shí)有框架提供的默認(rèn)的 Interceptor ,下面我來看看 Interceptor 使用的步驟:
          1、?? 創(chuàng)建一個(gè)自己需要的 Interceptor 類,它必需實(shí)現(xiàn)
          com.opensymphony.xwork.interceptor.Interceptor
          接口,具體的開發(fā)見下面的 Interceptor 的原理。
          2、?? 在配置文件( xwork..xml )中申明這個(gè) Interceptor 類,它放在標(biāo)簽 <interceptor /> 中,同是 <interceptor /> 標(biāo)簽嵌入在 <interceptors /> 標(biāo)簽內(nèi)部。
          3、?? 創(chuàng)建 Interceptor 棧,使用標(biāo)簽: <interceptor-stack?/> 讓一組 Interceptor 可以按次序調(diào)用。(可選)
          4、?? 指定 Action 所要用到的 Interceptor (前面申明過的),可以用 <interceptor-ref /> <default-interceptor-ref /> 標(biāo)簽。前面的標(biāo)簽指定某個(gè) Action 所用到的 Interceptor ,如果 Action 沒有被用 <interceptor-ref /> 指定 Interceptor ,它將使用 <default-interceptor-ref /> 指定的 Interceptor
          框架中給我們提供了很多實(shí)用的 Interceptor ,它的定義上面已經(jīng)給出,它的具體功能如下:
          l????????? timer :記錄 Action 執(zhí)行的時(shí)間,并做為日志信息輸出;
          l????????? logger :在日志信息中輸出要執(zhí)行的 Action 信息;
          l????????? chain :將前一個(gè)執(zhí)行結(jié)束的 Action 屬性設(shè)置到當(dāng)前的 Action 中。它被用在 ResultType 為“ chain ”指定結(jié)果的 Action 中,該結(jié)果 Action 對(duì)象會(huì)從 OgnlValueStack 中獲得前一個(gè) Action 對(duì)應(yīng)的屬性,它實(shí)現(xiàn) Action 鏈之間的數(shù)據(jù)傳遞;
          l????????? static-params :將 xwork.xml 配置文件里定義的 Action 參數(shù),設(shè)置到對(duì)應(yīng)的 Action 中。 Action 參數(shù)使用 <param /> 標(biāo)簽,是 <action /> 標(biāo)簽的直接子元素。我們這里定義的 Action 類必需實(shí)現(xiàn) com.opensymphony.xwork.config.entities . Parameterizable 接口;
          l????????? params :將 Request 請(qǐng)求的參數(shù)設(shè)置到相應(yīng) Action 對(duì)象的屬性中,用戶注冊(cè)例子用到過這個(gè)攔截器;
          l????????? model-driven :如果 Action 實(shí)現(xiàn) ModelDriven 接口,它將 getModel() 取得的模型對(duì)象存入 OgnlValueStack 中;
          l????????? component :激活組件功能支持,讓注冊(cè)過的組件在當(dāng)前 Action 中可用,即為 Action 提供 IoC (依賴倒轉(zhuǎn)控制)框架的支持;
          l????????? token :核對(duì)當(dāng)前 Action 請(qǐng)求( request )的有效標(biāo)識(shí),防止重復(fù)提交 Action 請(qǐng)求 (request) 。
          l????????? token-session :功能同上,但是當(dāng)提交無效的 Action 請(qǐng)求標(biāo)識(shí)時(shí),它會(huì)將請(qǐng)求數(shù)據(jù)保存到 session 中。
          l????????? validation :實(shí)現(xiàn)使用 xml 配置文件( {Action}-validation.xml )對(duì) Action 屬性值進(jìn)行驗(yàn)證,詳細(xì)請(qǐng)看后面介紹的驗(yàn)證框架。
          l????????? workflow :調(diào)用 Action 類的驗(yàn)證功能,假設(shè) Action 使用 ValidationAware 實(shí)現(xiàn)驗(yàn)證( ActionSupport 提供此功能),如果驗(yàn)證沒有通過, workflow 會(huì)將請(qǐng)求返回到 input 視圖( Action <result /> 中定義的)。
          l????????? servlet-config :提供 Action 直接對(duì) HttpServletRequest HttpServletResponse JavaServlet api 的訪問, Action 要實(shí)現(xiàn)相應(yīng)的接口,例如: ServletRequestAware ServletResponseAware 。如果必需要提供對(duì) JavaServlet api 的訪問,我們建議使用 ServletActionContext ,在前面 ActionContext 章節(jié)中有介紹。
          l????????? prepare :在 Action 執(zhí)行之前調(diào)用 Action prepare() 方法,這個(gè)方法是用來準(zhǔn)備 Action 執(zhí)行之前要做的工作。它要求我們的 Action 必需實(shí)現(xiàn) com.opensymphony.xwork . Preparable 接口
          conversionError :用來處理框架進(jìn)行類型轉(zhuǎn)化 (Type Conversion) 時(shí)的出錯(cuò)信息。它將存儲(chǔ)在 ActionContext 中的類型轉(zhuǎn)化( Type Conversion )錯(cuò)誤信息轉(zhuǎn)化成相應(yīng)的 Action 字段的錯(cuò)誤信息,保存在堆棧中。根據(jù)需要,可以將這些錯(cuò)誤信息在視圖中顯示出來。
          ?
          Interceptor 的原理
          下面我們來看看 Interceptor 是如何實(shí)現(xiàn)在 Action 執(zhí)行前后調(diào)用的:
          Action Interceptor 在框架中的執(zhí)行,是由 ActionInvocation 對(duì)象調(diào)用的。它是用方法: String invoke() throws Exception; 來實(shí)現(xiàn)的,它首先會(huì)依次調(diào)用 Action 對(duì)應(yīng)的 Interceptor ,執(zhí)行完成所有的 Interceptor 之后,再去調(diào)用 Action 的方法,代碼如下:
          if (interceptors.hasNext()) {
          Interceptor interceptor = (Interceptor) interceptors.next();
          resultCode = interceptor.intercept(this);
          } else {
          ??? ?if (proxy.getConfig().getMethodName() == null) {
          resultCode = getAction().execute();
          } else {
          ??????? resultCode = invokeAction(getAction(), proxy.getConfig());
          }
          }
          它會(huì)在攔截器棧中遍歷 Interceptor ,調(diào)用 Interceptor 方法:
          String intercept(ActionInvocation invocation) throws Exception; 。
          我們一直都提到, Interceptor 是在 Action 前后執(zhí)行,可是從上面的代碼我們看到的卻是執(zhí)行完所有 Interceptor intercept () 方法之后再去調(diào)用我們的 Action 。“在 Action 前后執(zhí)行”是如何實(shí)現(xiàn)的呢?我們來看看抽象類 AroundInterceptor intercept () 實(shí)現(xiàn):
          public String intercept(ActionInvocation invocation) throws Exception {
          ??????? String result = null;
          ?
          ??????? before(invocation);
          ??????? result = invocation.invoke();
          ??????? after(invocation, result);
          ?
          ??????? return result;
          ??? }
          原來在 intercept () 方法又對(duì) ActionInvocation invoke() 方法進(jìn)行遞歸調(diào)用, ActionInvocation 循環(huán)嵌套在 intercept () 中,一直到語句 result = invocation.invoke(); 執(zhí)行結(jié)束,即: Action 執(zhí)行完并返回結(jié)果 result ,這時(shí) Interceptor 對(duì)象會(huì)按照剛開始執(zhí)行的逆向順序依次執(zhí)行結(jié)束。這樣 before () 方法將在 Action 執(zhí)行前調(diào)用, after () 方法在 Action 執(zhí)行之后運(yùn)行
          WebWork 教程 - Interceptor( 攔截器 )
          Interceptor (攔截器)將 Action 共用的行為獨(dú)立出來,在 Action 執(zhí)行前后運(yùn)行。這也就是我們所說的 AOP Aspect Oriented Programming ,面向切面編程),它是分散關(guān)注的編程方法,它將通用需求功能從不相關(guān)類之中分離出來;同時(shí),能夠使得很多類共享一個(gè)行為,一旦行為發(fā)生變化,不必修改很多類,只要修改這個(gè)行為就可以。
          ?
          Interceptor 將很多功能從我們的 Action 中獨(dú)立出來,大量減少了我們 Action 的代碼,獨(dú)立出來的行為具有很好的重用性。 XWork 、 WebWork 的許多功能都是有 Interceptor 實(shí)現(xiàn),可以在配置文件中組裝 Action 用到的 Interceptor ,它會(huì)按照你指定的順序,在 Action 執(zhí)行前后運(yùn)行。 Interceptor 在框架中的應(yīng)用如下圖所示
          ?
          ?
          當(dāng)你提交對(duì) Aciton (默認(rèn)是 .action 結(jié)尾的 Url )的請(qǐng)求時(shí), ServletDispatcher 會(huì)根據(jù)你的請(qǐng)求,去調(diào)度并執(zhí)行相應(yīng)的 Action 。在 Action 執(zhí)行之前,調(diào)用被 Interceptor 截取, Interceptor Action 執(zhí)行前后運(yùn)行。
          ?
          我們?cè)谟脩糇?cè)的例子中就使用了取得 Request 請(qǐng)求參數(shù)的攔截器,配置文件中 <interceptor-ref name="params"/> 將攔截器 params 組裝到 RegisterAction 中?!?/span> params ”在我們的 webwork-default.xml 配置文件中有定義, webwork-default.xml 中攔截器的定義如下:
          ?
          <interceptors>
          ??????????? <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
          ??????????? <interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/>
          ??????????? <interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/>
          ??????????? <interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/>
          ??????????? <interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
          ??????????? <interceptor name="model-driven" class="com.opensymphony.xwork.interceptor.ModelDrivenInterceptor"/>
          ??????????? <interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
          ??????????? <interceptor name="token" class="com.opensymphony.webwork.interceptor.TokenInterceptor"/>
          ??????????? <interceptor name="token-session" class="com.opensymphony.webwork.interceptor.TokenSessionStoreInterceptor"/>
          ??????????? <interceptor name="validation" class="com.opensymphony.xwork.validator.ValidationInterceptor"/>
          ??????????? <interceptor name="workflow" class="com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor"/>
          ??????????? <interceptor name="servlet-config" class="com.opensymphony.webwork.interceptor.ServletConfigInterceptor"/>
          ??????????? <interceptor name="prepare" class="com.opensymphony.xwork.interceptor.PrepareInterceptor"/>
          ??????????? <interceptor name="conversionError" class="com.opensymphony.webwork.interceptor.WebWorkConversionErrorInterceptor"/>
          ??????????? <interceptor-stack name="defaultStack">
          ??????????????? <interceptor-ref name="static-params"/>
          ??????????????? <interceptor-ref name="params"/>
          ??????????????? <interceptor-ref name="conversionError"/>
          ??????????? </interceptor-stack>
          ??????????? <interceptor-stack name="validationWorkflowStack">
          ??????????????? <interceptor-ref name="defaultStack"/>
          ??????????????? <interceptor-ref name="validation"/>
          ??????????????? <interceptor-ref name="workflow"/>
          ??????????? </interceptor-stack>
          ??????? </interceptors>
          這些都時(shí)有框架提供的默認(rèn)的 Interceptor ,下面我來看看 Interceptor 使用的步驟:
          1、?? 創(chuàng)建一個(gè)自己需要的 Interceptor 類,它必需實(shí)現(xiàn)
          com.opensymphony.xwork.interceptor.Interceptor
          接口,具體的開發(fā)見下面的 Interceptor 的原理。
          2、?? 在配置文件( xwork..xml )中申明這個(gè) Interceptor 類,它放在標(biāo)簽 <interceptor /> 中,同是 <interceptor /> 標(biāo)簽嵌入在 <interceptors /> 標(biāo)簽內(nèi)部。
          3、?? 創(chuàng)建 Interceptor 棧,使用標(biāo)簽: <interceptor-stack?/> , 讓一組 Interceptor 可以按次序調(diào)用。(可選)
          4、?? 指定 Action 所要用到的 Interceptor (前面申明過的),可以用 <interceptor-ref /> <default-interceptor-ref /> 標(biāo)簽。前面的標(biāo)簽指定某個(gè) Action 所用到的 Interceptor ,如果 Action 沒有被用 <interceptor-ref /> 指定 Interceptor ,它將使用 <default-interceptor-ref /> 指定的 Interceptor 。
          框架中給我們提供了很多實(shí)用的 Interceptor ,它的定義上面已經(jīng)給出,它的具體功能如下:
          l????????? timer :記錄 Action 執(zhí)行的時(shí)間,并做為日志信息輸出;
          l????????? logger :在日志信息中輸出要執(zhí)行的 Action 信息;
          l????????? chain :將前一個(gè)執(zhí)行結(jié)束的 Action 屬性設(shè)置到當(dāng)前的 Action 中。它被用在 ResultType 為“ chain ”指定結(jié)果的 Action 中,該結(jié)果 Action 對(duì)象會(huì)從 OgnlValueStack 中獲得前一個(gè) Action 對(duì)應(yīng)的屬性,它實(shí)現(xiàn) Action 鏈之間的數(shù)據(jù)傳遞;
          l????????? static-params :將 xwork.xml 配置文件里定義的 Action 參數(shù),設(shè)置到對(duì)應(yīng)的 Action 中。 Action 參數(shù)使用 <param /> 標(biāo)簽,是 <action /> 標(biāo)簽的直接子元素。我們這里定義的 Action 類必需實(shí)現(xiàn) com.opensymphony.xwork.config.entities . Parameterizable 接口;
          l????????? params :將 Request 請(qǐng)求的參數(shù)設(shè)置到相應(yīng) Action 對(duì)象的屬性中,用戶注冊(cè)例子用到過這個(gè)攔截器;
          l????????? model-driven :如果 Action 實(shí)現(xiàn) ModelDriven 接口,它將 getModel() 取得的模型對(duì)象存入 OgnlValueStack 中;
          l????????? component :激活組件功能支持,讓注冊(cè)過的組件在當(dāng)前 Action 中可用,即為 Action 提供 IoC (依賴倒轉(zhuǎn)控制)框架的支持;
          l????????? token :核對(duì)當(dāng)前 Action 請(qǐng)求( request )的有效標(biāo)識(shí),防止重復(fù)提交 Action 請(qǐng)求 (request) 。
          l????????? token-session :功能同上,但是當(dāng)提交無效的 Action 請(qǐng)求標(biāo)識(shí)時(shí),它會(huì)將請(qǐng)求數(shù)據(jù)保存到 session 中。
          l????????? validation :實(shí)現(xiàn)使用 xml 配置文件( {Action}-validation.xml )對(duì) Action 屬性值進(jìn)行驗(yàn)證,詳細(xì)請(qǐng)看后面介紹的驗(yàn)證框架。
          l????????? workflow :調(diào)用 Action 類的驗(yàn)證功能,假設(shè) Action 使用 ValidationAware 實(shí)現(xiàn)驗(yàn)證( ActionSupport 提供此功能),如果驗(yàn)證沒有通過, workflow 會(huì)將請(qǐng)求返回到 input 視圖( Action <result /> 中定義的)。
          l????????? servlet-config :提供 Action 直接對(duì) HttpServletRequest HttpServletResponse JavaServlet api 的訪問, Action 要實(shí)現(xiàn)相應(yīng)的接口,例如: ServletRequestAware ServletResponseAware 。如果必需要提供對(duì) JavaServlet api 的訪問,我們建議使用 ServletActionContext ,在前面 ActionContext 章節(jié)中有介紹。
          l????????? prepare :在 Action 執(zhí)行之前調(diào)用 Action prepare() 方法,這個(gè)方法是用來準(zhǔn)備 Action 執(zhí)行之前要做的工作。它要求我們的 Action 必需實(shí)現(xiàn) com.opensymphony.xwork . Preparable 接口
          conversionError :用來處理框架進(jìn)行類型轉(zhuǎn)化 (Type Conversion) 時(shí)的出錯(cuò)信息。它將存儲(chǔ)在 ActionContext 中的類型轉(zhuǎn)化( Type Conversion )錯(cuò)誤信息轉(zhuǎn)化成相應(yīng)的 Action 字段的錯(cuò)誤信息,保存在堆棧中。根據(jù)需要,可以將這些錯(cuò)誤信息在視圖中顯示出來。
          ?
          Interceptor 的原理
          下面我們來看看 Interceptor 是如何實(shí)現(xiàn)在 Action 執(zhí)行前后調(diào)用的:
          Action Interceptor 在框架中的執(zhí)行,是由 ActionInvocation 對(duì)象調(diào)用的。它是用方法: String invoke() throws Exception; 來實(shí)現(xiàn)的,它首先會(huì)依次調(diào)用 Action 對(duì)應(yīng)的 Interceptor ,執(zhí)行完成所有的 Interceptor 之后,再去調(diào)用 Action 的方法,代碼如下:
          if (interceptors.hasNext()) {
          Interceptor interceptor = (Interceptor) interceptors.next();
          resultCode = interceptor.intercept(this);
          } else {
          ??? ?if (proxy.getConfig().getMethodName() == null) {
          resultCode = getAction().execute();
          } else {
          ??????? resultCode = invokeAction(getAction(), proxy.getConfig());
          }
          }
          它會(huì)在攔截器棧中遍歷 Interceptor ,調(diào)用 Interceptor 方法:
          String intercept(ActionInvocation invocation) throws Exception; 。
          我們一直都提到, Interceptor 是在 Action 前后執(zhí)行,可是從上面的代碼我們看到的卻是執(zhí)行完所有 Interceptor intercept () 方法之后再去調(diào)用我們的 Action ?!霸?/span> Action 前后執(zhí)行”是如何實(shí)現(xiàn)的呢?我們來看看抽象類 AroundInterceptor intercept () 實(shí)現(xiàn):
          public String intercept(ActionInvocation invocation) throws Exception {
          ??????? String result = null;
          ?
          ??????? before(invocation);
          ??????? result = invocation.invoke();
          ??????? after(invocation, result);
          ?
          ??????? return result;
          ??? }
          原來在 intercept () 方法又對(duì) ActionInvocation invoke() 方法進(jìn)行遞歸調(diào)用, ActionInvocation 循環(huán)嵌套在 intercept () 中,一直到語句 result = invocation.invoke(); 執(zhí)行結(jié)束,即: Action 執(zhí)行完并返回結(jié)果 result ,這時(shí) Interceptor 對(duì)象會(huì)按照剛開始執(zhí)行的逆向順序依次執(zhí)行結(jié)束。這樣 before () 方法將在 Action 執(zhí)行前調(diào)用, after () 方法在 Action 執(zhí)行之后運(yùn)行

          posted on 2006-09-01 13:39 Binary 閱讀(620) 評(píng)論(0)  編輯  收藏 所屬分類: Webwork


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 阿瓦提县| 迁安市| 盱眙县| 富蕴县| 瓮安县| 上饶县| 大关县| 彰化县| 海门市| 荔波县| 门源| 宜春市| 会东县| 蓬溪县| 澄迈县| 屏山县| 惠来县| 韶关市| 和田市| 南宁市| 商河县| 沛县| 岳普湖县| 肃南| 保靖县| 中阳县| 绵阳市| 沛县| 宾川县| 云梦县| 盐津县| 丹阳市| 彭州市| 新乐市| 通化市| 蒙城县| 株洲县| 若尔盖县| 巨鹿县| 常州市| 正蓝旗|