隨筆-15  評(píng)論-79  文章-0  trackbacks-0

          最近發(fā)現(xiàn)很多朋友連攔截器都不知道,于是想寫個(gè)BLOG總結(jié)一下。
          java攔截器的基本原理其實(shí)非常簡(jiǎn)單,說(shuō)白了就是動(dòng)態(tài)代理類。
          下面來(lái)看一個(gè)簡(jiǎn)單的例子
          首先,我建立一個(gè)攔截器的類InterceptorClass,這里的before()和after()方法是以后攔截器會(huì)執(zhí)行的方法
          CODE清單一:

          public class InterceptorClass {
           
          public void before()
            System.out.println(
          "攔截器InterceptorClass方法調(diào)用:before()!"); 
           }
           
           
          public void after()
               System.out.println(
          "攔截器InterceptorClass方法調(diào)用:after()!"); 
           }

          }

           

          我們模擬一個(gè)業(yè)務(wù)組件接口BusinessInterface,和一個(gè)業(yè)務(wù)組件實(shí)現(xiàn)類BusinessClass
          CODE清單二:

          public interface BusinessInterface {
           
          public void doSomething();
          }

           

          CODE清單三:

          public class BusinessClass implements BusinessInterface {
           
          public void doSomething() {
             System.out.println(
          "業(yè)務(wù)組件BusinessClass方法調(diào)用:doSomething()"); 
           }

          }

           

          然后,創(chuàng)建一個(gè)動(dòng)態(tài)代理類DynamicProxyHandler,這個(gè)類是集成InvocationHandler接口的,動(dòng)態(tài)類的原理實(shí)際上是使得當(dāng)你執(zhí)行一個(gè)動(dòng)態(tài)方

          法的時(shí)候,他可以把這個(gè)動(dòng)態(tài)方法dispatch到這個(gè)動(dòng)態(tài)類上來(lái)。這樣,你就可以在這個(gè)方法的前后嵌入自己的一些方法。
          CODE清單四:
          //包含了業(yè)務(wù)對(duì)象綁定動(dòng)態(tài)代理類的處理,并實(shí)現(xiàn)了InvocationHandler接口的invoke方法

          public class DynamicProxyHandler implements InvocationHandler {
           
          private Object business;//被代理對(duì)象
           private InterceptorClass inceptor = new InterceptorClass();//攔截器
           
           
          // 動(dòng)態(tài)生成一個(gè)代理類對(duì)象,并綁定被代理類和代理處理器
           public Object bind(Object business) {
             
          this.business = business;
             
          return Proxy.newProxyInstance(
               
          //被代理類的ClassLoader
               business.getClass().getClassLoader(),
               
          //要被代理的接口,本方法返回對(duì)象會(huì)自動(dòng)聲稱實(shí)現(xiàn)了這些接口
               business.getClass().getInterfaces(), 
               
          //代理處理器對(duì)象
               this);
           }


           
           // 代理要調(diào)用的方法,并在方法調(diào)用前后調(diào)用連接器的方法

           /**
            * 
          @param proxy  代理類對(duì)象
            * 
          @param method 被代理的接口方法
            * 
          @param args   被代理接口方法的參數(shù)
            * 
          @throws Throwable
            
          */

           
          public Object invoke(Object proxy, Method method, Object[] args)
             
          throws Throwable {
            Object result 
          = null;
            inceptor.before();
            result
          =method.invoke(business,args);
            inceptor.after();
            
          return result;
           }


          OK,我們來(lái)寫個(gè)類測(cè)試一下
          CODE清單五:

          public static void main(String[] args) {
            
          //生成動(dòng)態(tài)代理類實(shí)例
            DynamicProxyHandler handler = new DynamicProxyHandler();
            
          //生成待測(cè)試的業(yè)務(wù)組件對(duì)象
                  BusinessInterface business = new BusinessClass();
                  
          //將業(yè)務(wù)組件對(duì)象和動(dòng)態(tài)代理類實(shí)例綁定
                  BusinessInterface businessProxy = (BusinessInterface) handler.bind(business);
                  
          //用動(dòng)態(tài)代理類調(diào)用方法
                  businessProxy.doSomething();
           }


          來(lái)看看結(jié)果:


          近期struts2很流行,而且攔截器是struts2里面一個(gè)比較好的功能,下面舉個(gè)例子說(shuō)明一下攔截器在struts2中的用法。
          struts2對(duì)攔截器實(shí)現(xiàn)做了一個(gè)封裝,使得我們?cè)趯?shí)現(xiàn)的時(shí)候比較簡(jiǎn)單。
          首先我們要建一個(gè)攔截器類
          CODE清單六:

          public class AuthorizationInterceptor extends AbstractInterceptor {
           @Override
           
          public String intercept(ActionInvocation invocation) throws Exception {
            Map session 
          = invocation.getInvocationContext().getSession();
            String userName 
          = (String) session.get("userName");
            
          if ( userName != null && userName.equals("test")) {
             System.out.println(
          "攔截器:合法用戶登錄---");
             
          return invocation.invoke();
            }

            
          else
            
          {
             System.out.println(
          "攔截器:用戶未登錄---");
             
          return Action.LOGIN;
            }

           }

          }


          這個(gè)類是必須要繼承struts2包中提供的AbstractInterceptor類,這個(gè)類有一個(gè)抽象方法intercept,這個(gè)方法是必須要實(shí)現(xiàn)的。
          那么經(jīng)理在這個(gè)攔截器里面寫了一個(gè)簡(jiǎn)單的實(shí)現(xiàn),對(duì)url用戶合法性做了一個(gè)限制。

          接下來(lái)比較關(guān)鍵的是過濾器在struts2中的配置,先看看代碼
          CODE清單七:

          <package name="system" extends="struts-default">
            
          <interceptors>
             
          <!--  定義權(quán)限控制攔截器  -->
             
          <interceptor name="authority" 

          class
          ="com.sharesin.biz.common.intercepts.struts2.AuthorizationInterceptor"/>
             
          <!-- 定義一個(gè)包含權(quán)限控制的攔截器棧   -->
             
          <interceptor-stack name="mystack">
              
          <interceptor-ref name="defaultStack"></interceptor-ref>
              
          <interceptor-ref name="authority"></interceptor-ref>
             
          </interceptor-stack>
            
          </interceptors>
             
          <!--定義默認(rèn)攔截器   -->
                  
          <default-interceptor-ref name="mystack" />
             
          <!--定義全局處理結(jié)果   -->
            
          <global-results>
             
          <result name="login">index.jsp</result>
            
          </global-results>
            
          <action name="login_*" class="com.sharesin.biz.web.system.LoginAction" method="{1}">
             
          <result name="success">system/homepage.jsp</result>
            
          </action>
           
          </package>


          在interceptors節(jié)點(diǎn)里,我們可以定義多個(gè)攔截器,這里的名為authority的只是其中的一個(gè)。struts2的攔截器棧我是先執(zhí)行struts2默認(rèn)的攔

          截器defaultStack,然后再執(zhí)行我的。然后只需要用default-interceptor-ref標(biāo)簽設(shè)置好這個(gè)system包中的默認(rèn)攔截器為這個(gè)攔截器就OK了。

          struts2中引入了package這個(gè)概念,我覺得十分實(shí)用,當(dāng)然這對(duì)struts2攔截器也是個(gè)實(shí)惠,我們可以根據(jù)不同的action來(lái)分包和不同的攔截器


          ok,來(lái)運(yùn)行測(cè)試一下。


          結(jié)果..


           

           

           

           

           

          posted on 2010-09-06 17:21 張?jiān)猈on 閱讀(4516) 評(píng)論(3)  編輯  收藏 所屬分類: Java

          評(píng)論:
          # re: JAVA攔截器原理及Struts2擴(kuò)展 2011-05-16 13:46 | lixiujuan
          以上代碼中struts的運(yùn)行還是在測(cè)試類里運(yùn)行吧?怎么執(zhí)行不了啊,,,???  回復(fù)  更多評(píng)論
            
          # re: JAVA攔截器原理及Struts2擴(kuò)展 2011-05-27 08:54 | え經(jīng)理え
          確實(shí)在測(cè)試類里的,不過絕對(duì)運(yùn)行的了的..不然不會(huì)截圖...你報(bào)的什么錯(cuò)?..@lixiujuan
            回復(fù)  更多評(píng)論
            
          # re: JAVA攔截器原理及Struts2擴(kuò)展 2014-08-04 00:15 | 打破沙鍋問到底
          攔截器一直攔截 根本過不去啊 一直在登錄頁(yè)面 不管你怎么填
          Map session = invocation.getInvocationContext().getSession();
          String userName = (String) session.get("userName");

          這個(gè)userName 就是null值啊 另外這個(gè)get里的“userName” 隨意給的嗎  回復(fù)  更多評(píng)論
            

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 大英县| 新晃| 三门县| 漳州市| 昌江| 东台市| 江北区| 自贡市| 新平| 西宁市| 易门县| 佛山市| 太仆寺旗| 龙游县| 定襄县| 资中县| 蚌埠市| 康乐县| 栖霞市| 图木舒克市| 和硕县| 开平市| 汉中市| 辽阳市| 金沙县| 汉阴县| 定襄县| 安达市| 德江县| 永善县| 碌曲县| 河津市| 静安区| 阿拉善盟| 鄢陵县| 闽清县| 清徐县| 鸡泽县| 金川县| 天祝| 三亚市|