前边我们讲过了Struts2框架的如何防止表单的重复提交,就是在表单页面的表单标签内加一个<s:token></s:token>标签,然后在这个action节点的下边指定一个拦截器token或者tokenSession,然后若是token拦截器就需要在action节点的下边指定一个name="token.invalid"的result的响应页面的节点并且在这个页面内用<actionerror></actionerror>标签来获取表单重复提交的错误信息,若是使用tokenSession拦截器的话,不必配置result的响应页面,那么不会执行tokenSession拦截器之后的拦截器和action方法,却依然会响应目标页面,就好像什么都没发生一样。
今天我们来讲一讲自定义拦截器应该如何使用
① Struts2的拦截器
拦截器是Struts2的核心部分,Struts2的很多功能都是构建在拦截器基础上的,如文件的上传和下载、国际化。数据类型转换、表单验证(包括字段验证和非字段验证)
② 拦截器之间、Action方法、result节点的调用顺序
拦截器是在访问某个Action方法的前后进行拦截处理工作的,根据Struts2的运行流程可知,Struts2将会按照拦截器栈的书写顺序依次调用拦截器,然后当最后一个拦截器的invoke()方法调用之后,ActionInvocation对象会去调用Action方法和渲染result响应页面,再之后再按照拦截器栈中反向的书写顺序依次调用拦截器invoke()方法之后的内容。
③ 拦截器的可插拔性
拦截器具有可插拔性,我们知道每个action请求的节点都是有默认指定的拦截器栈,我们如果希望增添新的功能,就可以在每个action节点的下边再指定一个自定义的拦截器,并将其写在默认拦截器栈的上方,那么,在处理这个action请求时,这个自定义拦截器就会先进行拦截,然后回调ActionInvocation接口实例的invoke()方法,接着下边的拦截器来执行。 如果我们希望自定义的拦截器当功能未完成时就不执行之后的拦截器和Action方法,那么我们可以在这个拦截器的interceptor()方法中写明当功能完成失败时提前返回一个String值而不去调用ActionInvocation的invoke()方法即可。这也是拦截器的可插拔性带给我们的好处,我们利用这个好处完成很多功能,已知的有token/tokenSession拦截器,ConversionError拦截器,权限验证和用户登录验证等等。由此,我们可以得出如果我们希望在一个拦截器栈或者一系列拦截器中当某个拦截器未达到我们想要的功能时,就终止之后的拦截器的功能和Action方法的功能,那么我们可以通过修改拦截器的interceptor()方法,即在这个方法中做一个判断,如果满足条件,就调用ActionInvocation实例对象的invoke()方法,如果不满足条件,就不调用这个方法二是返回一个String值到匹配这个String值的响应页面。
④ Interceptor接口
每个拦截器都实现了Interceptor接口或者其子类,并重写了这个接口中的三个方法,init这个方法在拦截器对象被初始化的之后立即被调用,这个方法在拦截器对象的生命周期内只出现了一次,可以在此方法中对相关的资源进行初始化;interceptor方法每拦截一个action请求,这个方法就会被调用一次;destroy方法,这个方法是在拦截器对象被销毁的时候被调用,也是像init方法一样,在整个拦截器的生命周期内只会被调用一次。需要注意的是,这个拦截器和Servlet和过滤器都比较像,加上构造器都是有四个方法。
Struts2框架会在defaultActionInvocation中根据在配置文件中获取的一系列的拦截器来遍历这些拦截器的interceptor()方法,每次调用某个拦截器的interceptor方法的时候都会向这个方法中传入一个ActionInvocation接口的实例(在defaultActionInvocation中传入的是this),ActionInvocation实际上呢是代表给定的Action的执行状态,拦截器可以从该类的对象当中获取与Action关联的Action对象和Result对象,在完成拦截器自己的功能之后,会调用这个ActionInvocation对象的invoke方法,进入到下一个环节。
一般定义一个自定义拦截器的话,可以选择继承AbstractInterceptor抽象类,内含空的init和destroy方法,无参空的构造器和一个抽象的interceptor方法。
⑤ 自定义拦截器
首先我们需要写一个实现Interceptor接口或者其子类的普通的java类,然后在struts.xml文件中配置引用这个拦截器类的action节点的<interceptor-ref/>和全局拦截器<interceptor name class/>即可。
今天我们来讲一讲自定义拦截器应该如何使用
① Struts2的拦截器
拦截器是Struts2的核心部分,Struts2的很多功能都是构建在拦截器基础上的,如文件的上传和下载、国际化。数据类型转换、表单验证(包括字段验证和非字段验证)
② 拦截器之间、Action方法、result节点的调用顺序
拦截器是在访问某个Action方法的前后进行拦截处理工作的,根据Struts2的运行流程可知,Struts2将会按照拦截器栈的书写顺序依次调用拦截器,然后当最后一个拦截器的invoke()方法调用之后,ActionInvocation对象会去调用Action方法和渲染result响应页面,再之后再按照拦截器栈中反向的书写顺序依次调用拦截器invoke()方法之后的内容。
③ 拦截器的可插拔性
拦截器具有可插拔性,我们知道每个action请求的节点都是有默认指定的拦截器栈,我们如果希望增添新的功能,就可以在每个action节点的下边再指定一个自定义的拦截器,并将其写在默认拦截器栈的上方,那么,在处理这个action请求时,这个自定义拦截器就会先进行拦截,然后回调ActionInvocation接口实例的invoke()方法,接着下边的拦截器来执行。 如果我们希望自定义的拦截器当功能未完成时就不执行之后的拦截器和Action方法,那么我们可以在这个拦截器的interceptor()方法中写明当功能完成失败时提前返回一个String值而不去调用ActionInvocation的invoke()方法即可。这也是拦截器的可插拔性带给我们的好处,我们利用这个好处完成很多功能,已知的有token/tokenSession拦截器,ConversionError拦截器,权限验证和用户登录验证等等。由此,我们可以得出如果我们希望在一个拦截器栈或者一系列拦截器中当某个拦截器未达到我们想要的功能时,就终止之后的拦截器的功能和Action方法的功能,那么我们可以通过修改拦截器的interceptor()方法,即在这个方法中做一个判断,如果满足条件,就调用ActionInvocation实例对象的invoke()方法,如果不满足条件,就不调用这个方法二是返回一个String值到匹配这个String值的响应页面。
④ Interceptor接口
每个拦截器都实现了Interceptor接口或者其子类,并重写了这个接口中的三个方法,init这个方法在拦截器对象被初始化的之后立即被调用,这个方法在拦截器对象的生命周期内只出现了一次,可以在此方法中对相关的资源进行初始化;interceptor方法每拦截一个action请求,这个方法就会被调用一次;destroy方法,这个方法是在拦截器对象被销毁的时候被调用,也是像init方法一样,在整个拦截器的生命周期内只会被调用一次。需要注意的是,这个拦截器和Servlet和过滤器都比较像,加上构造器都是有四个方法。
Struts2框架会在defaultActionInvocation中根据在配置文件中获取的一系列的拦截器来遍历这些拦截器的interceptor()方法,每次调用某个拦截器的interceptor方法的时候都会向这个方法中传入一个ActionInvocation接口的实例(在defaultActionInvocation中传入的是this),ActionInvocation实际上呢是代表给定的Action的执行状态,拦截器可以从该类的对象当中获取与Action关联的Action对象和Result对象,在完成拦截器自己的功能之后,会调用这个ActionInvocation对象的invoke方法,进入到下一个环节。
一般定义一个自定义拦截器的话,可以选择继承AbstractInterceptor抽象类,内含空的init和destroy方法,无参空的构造器和一个抽象的interceptor方法。
⑤ 自定义拦截器
首先我们需要写一个实现Interceptor接口或者其子类的普通的java类,然后在struts.xml文件中配置引用这个拦截器类的action节点的<interceptor-ref/>和全局拦截器<interceptor name class/>即可。