JAVA拦截器原理及Struts2扩展

系统 1616 0

最近发现很多朋友连拦截器都不知道,于是想写个BLOG总结一下。
java拦截器的基本原理其实非常简单,说白了就是动态代理类。
下面来看一个简单的例子
首先,我建立一个拦截器的类InterceptorClass,这里的before()和after()方法是以后拦截器会执行的方法
CODE清单一:

    
      //拦截器
public class InterceptorClass {
    public void before() {
        System.out.println("拦截器InterceptorClass方法调用:before()!");
    }

    public void after() {
        System.out.println("拦截器InterceptorClass方法调用:after()!");
    }
}
    
  

  

 

我们模拟一个业务组件接口BusinessInterface,和一个业务组件实现类BusinessClass
CODE清单二:

    
      /**
 * Created by IntelliJ IDEA.
 * User: Ming
 * Date: 2010-9-7
 * Time: 8:45:26
 */
//业务组件接口
public interface BusinessInterface {

    public void doSomething();
}
    
  

    

 

 

CODE清单三:

    
      /**
 * Created by IntelliJ IDEA.
 * User: Ming
 * Date: 2010-9-7
 * Time: 8:46:27
 */
//业务组件实现类
public class BusinessClass implements BusinessInterface {
    public void doSomething() {
        System.out.println("业务组件BusinessClass方法调用:doSomething()");
    }
}
    
  

 

 

然后,创建一个动态代理类DynamicProxyHandler,这个类是集成InvocationHandler接口的,动态类的原理实际上是使得当你执行一个动态方

法的时候,他可以把这个动态方法dispatch到这个动态类上来。这样,你就可以在这个方法的前后嵌入自己的一些方法。
CODE清单四:

    
      /**
 * Created by IntelliJ IDEA.
 * User: Ming
 * Date: 2010-9-7
 * Time: 8:50:35
 */

/**
 * 动态代理类,实现InvocationHandler接口.
 * 包含了业务对象绑定动态代理类的处理
 */
public class DynamicProxyHandler implements InvocationHandler {
    private Object business;//被代理对象
    private InterceptorClass inceptor = new InterceptorClass();//拦截器

    public DynamicProxyHandler(Object business) {
        this.business = business;
    }
    
  

   
 // 代理要调用的方法,并在方法调用前后调用连接器的方法

 

 

    
      /**
     * @param proxy    代理类对象
     * @param method   被代理的接口方法
     * @param args      被代理接口方法的参数
     * @return
     * @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,我们来写个类测试一下
CODE清单五:

    
          public static void main(String[] args) {
        //生成待测试的业务组件对象
        BusinessInterface business = new BusinessClass();
        //生成动态代理类实例
        DynamicProxyHandler handler = new DynamicProxyHandler(business);

        BusinessInterface businessProxy = (BusinessInterface) Proxy.newProxyInstance(
                //被代理类的ClassLoader
                business.getClass().getClassLoader(),
                //要被代理的接口,本方法返回对象会自动声称实现了这些接口
                business.getClass().getInterfaces(),
                //代理处理器对象
                handler);
        //用动态代理类调用方法
        businessProxy.doSomething();
    }
    
  

 
来看看结果:


近期struts2很流行,而且拦截器是struts2里面一个比较好的功能,下面举个例子说明一下拦截器在struts2中的用法。
struts2对拦截器实现做了一个封装,使得我们在实现的时候比较简单。
首先我们要建一个拦截器类
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;
  }
 }
}

    
  

 

 


这个类是必须要继承struts2包中提供的AbstractInterceptor类,这个类有一个抽象方法intercept,这个方法是必须要实现的。
那么经理在这个拦截器里面写了一个简单的实现,对url用户合法性做了一个限制。

接下来比较关键的是过滤器在struts2中的配置,先看看代码
CODE清单七:

 

    
      <package name="system" extends="struts-default">
  <interceptors>
   <!--  定义权限控制拦截器  -->
   <interceptor name="authority" 

class="com.sharesin.biz.common.intercepts.struts2.AuthorizationInterceptor"/>
   <!-- 定义一个包含权限控制的拦截器栈   -->
   <interceptor-stack name="mystack">
    <interceptor-ref name="defaultStack"></interceptor-ref>
    <interceptor-ref name="authority"></interceptor-ref>
   </interceptor-stack>
  </interceptors>
   <!--定义默认拦截器   -->
        <default-interceptor-ref name="mystack" />
   <!--定义全局处理结果   -->
  <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节点里,我们可以定义多个拦截器,这里的名为authority的只是其中的一个。struts2的拦截器栈我是先执行struts2默认的拦

截器defaultStack,然后再执行我的。然后只需要用default-interceptor-ref标签设置好这个system包中的默认拦截器为这个拦截器就OK了。

struts2中引入了package这个概念,我觉得十分实用,当然这对struts2拦截器也是个实惠,我们可以根据不同的action来分包和不同的拦截器


ok,来运行测试一下。

 

JAVA拦截器原理及Struts2扩展


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论