struts2-拦截器
struts2 拦截器(interceptor)简介:
拦截器(interceptor)是struts2框架的一个核心组件,struts2框架的大部分功能都是通过拦截器来完成的,例如数据校验、国际化、文件上传和下载等。
拦截器实现了动态拦截Action调用的功能。开发者可以定义一个拦截器在Action调用前后执行一些处理;同时它也提供了一种将通用代码模块化的方式,可以把多个Action中重复指定的代码提取出来,统一放在拦截器里定义使用。
拦截器(interceptor)使用:
1.拦截器使用标签interceptor配置在struts.xml文件中,interceptor标签有两个属性分别是name、class,其中name指定拦截器的名称,class指定拦截器实现的类。
示例:
<interceptors>
<interceptor name="interceptor_example" class="com.example.interceptor.InterceptorDemo"/>
</interceptors>
定义的拦截器(interceptor)也可以传入参数,例如:
<interceptor name="interceptor_example" class="com.example.interceptor.InterceptorDemo">
<param name="interceptor_paramName">interceptor_paramValue</param>
</interceptor>
2.拦截器栈
拦截器栈实际上是为方便开发者使用多个拦截器而定义的。
首先:需要定义拦截器;然后:将多个拦截器引用在一个拦截器栈中;最后:Action引用该拦截器栈,即可使用该拦截器栈中的所有拦截器,拦截器栈也可以引用拦截器栈。
拦截器栈定义的标签为:interceptor-stack,子标签:interceptor-ref ,这两个标签具有一个name属性,用于设置或引用拦截器的名称。
示例:
<interceptors>
<interceptor name="interceptor1" class="com.example.interceptor.InterceptorDemo"/>
<interceptor name="interceptor1" class="com.example.interceptor.InterceptorDemo"/>
<interceptor-stack name='interceptor-stack-demo">
<interceptor-ref name='interceptor1"/>
<interceptor-ref name='interceptor2"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
备注:defaultStack是struts2框架内置的拦截器栈。
3.默认拦截器
在一个包(package)中同时为多个action配置相同的拦截器时可以使用default-interceptor-ref标签,注意一旦某个action显式配置了拦截器那么默认拦截器就会被屏蔽,不会起作用,除非为该action显式添加默认拦截器(其他未显式配置拦截器的action,默认拦截器正常生效)。每个包(package)下只能定义一个默认拦截器。
示例:
<package name="default" extends="struts-default">
<interceptors>
<interceptor name="interceptor1" class="com.example.interceptor.InterceptorDemo"/>
<interceptor name="interceptor2" class="com.example.interceptor.InterceptorDemo2"/>
</interceptors>
<defautl-interceptor-ref name="interceptor1"/>
<action name="action1" class="com.example.action.DemoAction">
……
</action>
<action name="action2" class="com.example.action.Demo2Action">
……
</action>
<action name="action3" class="com.example.action.DemoAction">
<interceptor-ref name="interceptor2"/>
……
</action>
</package>
说明:action1 和 action2 使用的是默认拦截器,action3使用的是显式配置的拦截器(默认拦截器不生效),在action中也可以为拦截器赋值和上面写的拦截器赋值方式一样,拦截器栈的赋值方式是拦截器名+参数名,例如:interceptorName.paramName。
struts2框架提供一些拦截器,可以直接配置使用,此处不再一一介绍
自定义拦截器
开发者在定义自己的拦截器时,需要实现com.opensymphony.xwork2.interceptor.Interceptor接口,Interceptor接口的源码如下:
public interface Interceptor extends Serializable{
void init();
void destroy();
String interceptor(ActionInvocation invocation)throws Exception;
}
我们自定义的拦截器只需要实现上面的三个方法即可;
init():在拦截器执行之前调用,主要用于初始化系统资源,对于一个拦截器而言,init方法只会被调用一次。
destroy():与init方法对应,在拦截器实例被销毁之前,系统将会调用该方法来释放和拦截器相关的资源。
interceptor():是拦截器的核心方法,所有的拦截代码在该方法中实现;它返回一个字符串作为逻辑视图,系统根据返回的字符串跳转到对应的视图资源。参数ActionInvocation包含了被拦截的Action的引用,通过该参数的invoke()方法将控制权交给下一个拦截器或者Action的excetue()方法。
Struts2框架为了简化开发已帮我们实现了该接口,我们只需要继承其抽象类AbstractInterceptor、MethodFilterInterceptor类接口,其中继承AbstractInterceptor类的拦截器时使用于Action类中的所有方法;继承MethodFilterInterceptor类的拦截器适用于指定Action类中某些方法可以被拦截、某些方法不被拦截。MethodFilterInterceptor类增加了两个额外的方法 includeMethods 和 excludeMethods。
public void setExcludeMethods(String excludeMethods):excludeMethods参数用于排除需要过滤掉的方法名。
public void setIncludeMethods(String includeMethods):includeMethods参数列出的所有方法都会被拦截。
说明:在继承MethodFilterInterceptor类时这两个方法不需要重写,只需重写doIntercept方法即可。
继承AbstractInterceptor的拦截器主要实现interceptor()方法即可,有需求可以重写抽象类的 init() 和 destroy()方法。
继承MethodFilterInterceptor的拦截器主要实现doInterceptor方法即可,有需求可重写抽象类的 init() 和 destroy()方法。
示例:
public class MyInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation invocation){
// #1 拦截业务逻辑代码
……
String result=invocation.invoke();
// #2 拦截业务逻辑代码
……
}
}
public class MyMethodInterceptor extends MethodFilterInterceptor{
@Override
public String doIntercept(ActionInvocation invocation){
// #1 拦截业务逻辑代码
……
String result=invocation.invoke();
// #2 拦截业务逻辑代码
……
}
}
拦截器执行顺序:按照struts.xml文件配置的顺序由上往下(由外往内)执行,然后由内往外执行,例如上例先执行 invocation.invoke()上面的 #1代码 然后调用下一个拦截器依次执行,直到执行Action的excute方法后,由内往外在执行 invocation.invoke()下面的#2代码 所有的拦截都是以此类推执行的。
自定义拦截器的配置使用和上述拦截器配置方式一样,方法过滤拦截器增加了两个参数分别是 includeMethods(拦截的方法) 和 excludeMethods(排除拦截的方法),示例:
<interceptor name="methodFilterInterceptor" class ="com.example.interceptor.MyMethodFilterInterceptor">
<param name="includeMethods"> method1,method2 ,method3</param>
<param name="excludeMethods">method4,method5</param>
</interceptor>
说明:其中参数名includeMethods的值是需要被过滤拦截的方法,参数名excludeMethods的值是不需要被过滤拦截的方法;多个方法之间用逗号“,”隔开;另外如果两个参数名中都有同一个方法名则此方法会被过滤拦截的。