概念

拦截器

    在AOP中用于在某个方法或字段被访问之前,进行拦截然后在之前或者之后加入某些操作。拦截是AOP的一种实现策略。

    在webwork中解释是动态拦截action调用的对象。提供一种机制可以使开发者定义一个action执行的前后执行的代码,也可以在action执行前阻止其执行,同时也提供了一种可以提取action中可重用的部分的方式

拦截器栈

     在struts2中存在拦截器栈Interceptor Stack,也可以称为InterceptorChain。就是讲拦截器按一定顺序联结成一条链。在访问拦截器的方法或字段的时候,拦截器联众的拦截器就会按顺序进行调用。

实现原理

    大部分时候拦截器方法使用代理的方式来调用。Struts2中拦截器相对简单,请求到ServletDispatcher时,Struts2查询配置文件,根据配置实例化相对的拦截器对象,串成一个列表,然后按顺序调用表中的拦截器。

拦截器API

自定义拦截器有三个API,拦截器的生命周期:随项目启动而创建,随项目的关闭而销毁。

方式一:实现接口Interceptor


public class MyInterceptor implements Interceptor {
@Override
// 初始化
public void init() {
}
@Override
// 拦截器
public String intercept(ActionInvocation arg0) throws Exception {
return null;
}
@Override
// 销毁
public void destroy() {
}

}


   实现接口需要实现其中三个方法,如果init,destroy不是使用也需要实现,所以不推荐使用。

方式二:继承抽象的abstractInterceptor


public class Myinterceptor2 extends AbstractInterceptor {

@Override
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
return null;
}

}

    本质是abstractInterceptor实现了Interceptor接口,把intercept()方法设置为抽象,并对里面的init()和destroy()进行空实现。子类继承abstractInterceptor相对接口要简单。

方式三:继承MethodFilterInterceptor

此种方式称为方法过滤拦截器


public class MyInterceptor3 extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
return null;
}
}

    本质继承abstractInterceptor,并且提供一种机制,可以指定action中某些方法进行拦截或者不拦截,相对于前两种更加灵活。

自定义拦截器

    利用方式三编写自定义拦截器


public class MyInterceptor3 extends MethodFilterInterceptor{

@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
//前处理
System.out.println("MyInterceptor3的前处理");
//放行
invocation.invoke();
//后处理
System.out.println("MyInterceptor3的后处理");
return "success";
}
}

配置文件struts.xml


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="inter" namespace="/" extends="struts-default" >
<!--注册拦截器-->
<interceptors>
<interceptor name="myInter3" class="cn.xiaojia.a_interceptor.MyInterceptor3"/>
<!-- 注册拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 自定义拦截器引入(建议放在20个拦截器之前) -->
<interceptor-ref name="myInter3">
<!-- 指定哪些方法是不拦截的
<param name="excludeMethods">add,delete</param>-->
<!-- 指定哪些方法是拦截的 拦截和不拦截不能同时指定 -->
<param name="includeMethods">add,delete</param>
</interceptor-ref>
<!-- 引用默认的拦截器栈(20个) -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="Demo1Action_*" class="cn.xiaojia.a_interceptor.Demo1Action" method="{1}">
<!-- 为Action单独指定走哪个拦截器
<interceptor-ref name="myStack"></interceptor-ref>-->
<result name="success" type="dispatcher">/index.jsp</result>
</action>

</package>
</struts>

测试类


public class Demo1Action extends ActionSupport{

public String add() throws Exception {
System.out.println("Demo1Action_add");
return SUCCESS;
}
public String delete() throws Exception {
System.out.println("Demo1Action_delete");
return SUCCESS;
}
public String update() throws Exception {
System.out.println("Demo1Action_update");
return SUCCESS;
}
public String find() throws Exception {
System.out.println("Demo1Action_find");
return SUCCESS;
}

}

执行结果

【菜鸟学框架】——Struts2自定义拦截器_ide

【总结】


    其实自定义拦截器也挺容易的,主要的内容配置文件上。其中我认为需要注意的就是方法拦截过滤器的拦截方法的配置,拦截和不拦截只能二选一。文中如有理解偏颇之处,欢迎各位大神拍砖,不胜感激!