struts2拦截器的实现
拦截器顾名思义,就是当有请求访问action时候,拦截器拦截下请求进行某些操作(但是呢,当请求到来时,请求会先到达action类的构造方法,再到达拦截器)。这是请求访问action的时序图:
在struts2当中自带这很多很强大的拦截器,那么是不是我们自己实现一个自定义的struts2的拦截器是不是也就很困难了?答案是否定的。相反,实现struts2的自定义拦截器是相当的容易的。
实现接口方式实现一个自定义的struts2拦截器:
所需实现接口:com.opensymphony.xwork2.interceptor.Interceptor
实现了该接口,也必须实现接口下的三个方法:
init():这是拦截器的初始化方法,在服务器启动只是就会触发该方法,也可以在这方法进行一些初始化的操作,比如对一个字段进行赋值等等。但是呢,在对一个属性进行赋值时候,必须给该属性实现get/set方法。否则是不可以实现对该实行赋值的,怎么赋值呢?一般可以在struts.xml中定义拦截器时候进行赋值,待会再进一步的描述如何进行赋值。
intercept():这个方法是拦截器的核心方法,主要是实现拦截器的逻辑处理等等操作。在请求访问action时候,就会进入到该方法。在这方法中要调用arg0.invoke()。在请求访问action时候,会先进入到该方法,执行arg0.invoke()前代码逻辑语句,执行到arg0.invoke()时,方法action类的相关操作,之后调用action的会调execute。在执行完action的相关操作,在执行到arg0.invoke()后面的逻辑代码,按照堆栈的方法逐个的访问拦截器退出。
destroy():这是struts2拦截器的销毁操作,在拦截器被销毁时候就会执行到该方法。
如何配置struts2拦截器呢?
在struts.xml当中,在package内的顶部配置拦截器。
<interceptors></interceptors>声明拦截器
<interceptor></interceptor>配置拦截器
<param></param>给该拦截器内的属性初始化,如不用初始化拦截器内的属性,则不需添加该标签,name值要与拦截器的属性一致。
<interceptor-ref></interceptor-ref>在action标签内引用已配置的拦截器。
但是细心的伙伴也会发现,在<interceptor-ref></interceptor-ref>标签内也有<param></param>标签,但是呢,改标签也是与配置拦截器时候的而是用方法一致的。但是值得我们注意的是,在相同的拦截器进行相同的属性进行初始化成为不同的值,先后顺序是:配置--->引用。引用时候赋值会覆盖了配置时候赋的值。现在又有一个问题来了,拦截器init方法到底如何被调用呢,也就是说,到底是在声明配置拦截器时候调用还是在引用拦截器时候被调用?根据对拦截器属性的初始化以及init方法打印语句来看:当action标签中出现了引用拦截器时,会在引用之后调用该拦截器。
在添加拦截器时候,千万别忘了添加struts2默认的拦截器<interceptor-ref name="defaultStack"></interceptor-ref>,系统默认的对不添加拦截器的action添加上了改拦截器,但是我们主动的添加拦截器之后,会覆盖掉该方法。不添加很容易会出现意想不到的等情况。
配置示例代码:
<package name="default" namespace="/" extends="struts-default"> <interceptors> <interceptor name="firstInterceptor" class="com.usc.geowind.lilin.interceptors.FirstInterceptor"> <param name="name">gaosi</param> </interceptor> </interceptors> <!--method属性指定是action触发的方法 --> <action name="firstAction" class="com.usc.geowind.lilin.actions.FirstAction" method="execute"> <interceptor-ref name="firstInterceptor"> <param name="name"> lilin</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> <!-- 结果指向 --> <!-- name属性是指定接收的action返回来的字符串数值 --> <result name="success"> /success.jsp </result> <result name="fail"> /fail.jsp </result> </action> </package>
这样自定义拦截器就基本配置完成了。
当我们要在几个action当中,引用相同拦截器,会不会上面介绍的方法会出现代码冗余的状况?答案是肯定的。这时候就有一个新的概念:拦截器栈队。拦截器栈队:将若干个相同的拦截器打包成为一个拦截器组,在action中引用该拦截器组就可以了。
<package name="default" namespace="/" extends="struts-default"> <interceptors> <!-- 配置拦截器 --> <interceptor name="firstInterceptor" class="com.usc.geowind.lilin.interceptors.FirstInterceptor"> <param name="name">gaosi</param> </interceptor> <!-- 拦截器栈队 --> <interceptor-stack name="allInterceptor"> <interceptor-ref name="firstInterceptor"> <param name="name"> lilin</param> </interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!--method属性指定是action触发的方法 --> <action name="firstAction" class="com.usc.geowind.lilin.actions.FirstAction" method="execute"> <!-- 引用拦截器栈队 --> <interceptor-ref name="allInterceptor"></interceptor-ref> <!-- 结果指向 --> <!-- name属性是指定接收的action返回来的字符串数值 --> <result name="success"> /success.jsp </result> <result name="fail"> /fail.jsp </result> </action> </package>
<interceptor-stack></interceptor-stack>就是拦截器栈队。将所需的拦截器加到栈队中就可。
配置默认的拦截器
<default-interceptor-ref></default-interceptor-ref>在改标签中可以配置struts拦截器,在action中不引用拦截器的情况下,struts会默认的引用该默认拦截器
方法拦截器:
在类中需要继承com.opensymphony.xwork2.interceptor.MethodFilterInterceptor类并重写方法doIntercept()
在配置当中有那么一点不同。
对add,delete方法进行拦截
<interceptor name="MethodInterceptor" class="com.usc.geowind.lilin.interceptors.SecINterceptor"> <param name="includeMethods">add,delete</param> </interceptor>
也可以对某方法进行不拦截:如,对delete ,add方法进行不拦截
<interceptor name="MethodInterceptor" class="com.usc.geowind.lilin.interceptors.SecINterceptor"> <param name="excludeMethods">add,delete</param> </interceptor>
拦截器的基本内容就这些了,但是拦截器还是有很大的作用的,有待继续深入了解。