struts2中的拦截器详解以及拦截器与过滤器的区别
1、拦截器的概述
在Webwork的中文文档的解释为--拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者在定义的action执行的前后加入执行的代码,也可以在一个action执行前阻止其执行。也就是说它提供了一种可以提取action中可重复代码,统一管理和执行的方式。
在web中,我们了解了过滤器,那么过滤器与拦截器有什么区别呢?
(1)、过滤器是servlet规范中的一部分,任何java web工程都可以使用。
(2)、拦截器是struts2框架自己的,只有使用了struts2框架的工程才能用。
(3)、过滤器在url-pattern中配置/*之后,可以对所有要访问的资源拦截。
(4)、拦截器它是只有进入struts2核心内部之后,才会起作用,如果访问的是jsp,html,css,image或者js是不会进行拦截的。同时拦截器还是AOP编程思想的具体体现形式。AOP简单的说就是:在不修改源码的基础上,对已有的方法进行动态增强。在struts2中,拦截器它就是对我们的动作方法进行增强(其实就是把重复性的代码提取出来,然后放到拦截器中,统一管理,统一调用)。
2、拦截器的执行时机
在访问struts2中的action时,会正序的执行拦截器,放行后再执行动作方法,执行完,再倒序执行。所以它是先进后出,是个栈结构的执行方式。
3、拦截器的创建方式
(1)、实现拦截器接口Interceptor
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInter implements Interceptor{
@Override
public void destroy() {
//拦截器的销毁方法
}
@Override
public void init() {
//拦截器的初始化方法
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//拦截器的拦截方法
return null;
}
}
从拦截器的接口中,我们可以知道拦截器的生命周期是属于创建一次,然后整个项目都可以使用,是单例的。
(2)、继承抽象类AbstractInterceptor
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyInter extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//拦截器的执行方法
return null;
}
}
从继承后要重写的方法,我们可以知道
AbstractInterceptor帮我们实现了Interceptor接口中的init()、destory()方法。
(3)、继承抽象类MethodFilterInterceptor
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class MyInter extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
//拦截器的拦截执行方法
return null;
}
}
这个抽象类中的功能有了增强,可以对拦截的方法进行过滤,可以指定拦截哪些Action方法或不拦截哪些Action方法,使用起来更加的方便,所以我们通常使用的是第三种方法。下面我的例子也是针对第三种方法。
4、拦截器在struts.xml中的配置
在package下配置
<interceptors>
<!--
注册拦截器
name:为你为自己拦截器起的名字
class:自定义拦截器的类的全路径
-->
<interceptor name="myInter" class="com.haha.web.interceptor.MyInteceptor"></interceptor>
<!-- 配置拦截器栈 -->
<interceptor-stack name="myStack">
<!--在拦截器栈中配置自己注册的拦截器 -->
<interceptor-ref name="myInter">
<!--excludeMethods是拦截器不拦截哪个方法 includeMethods是拦截器拦截那个方法 -->
<param name="excludeMethods">login</param>
</interceptor-ref>
<!--配置默认的20个拦截器 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 指定默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
注意:如果你在这个配置文件中引用了其他的配置文件,这个拦截器对其他的配置文件中配置的action是不起作用的,因为他们不在同一个package下,如果你向在多个配置文件中共用一个拦截器配置,你可以把这个拦截器提取出来,重新写一个配置文件,然后让其他的配置文件去继承这个配置文件即可。
5、拦截器拦截的例子
import com.haha.domain.User;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class MyInteceptor extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
User user =(User) ActionContext.getContext().getSession().get("user");
if(user!=null){
//放行方法
return invocation.invoke();
}
//不放行的话返回一个其他的字符串
return "tologin";
}
}
其中的invocation.invoke()就是放行的方法。它会在访问你的action中的方法之前去执行拦截器,如果放行就接着执行你所要执行的方法,如果不放行,就不会执行你要执行的方法。