Struts 2学习及问题记录(4)——拦截器机制
2016-05-23 10:00
567 查看
拦截器体系是Struts 2框架的重要组成部分,可以把Struts 2理解成一个空容器,而大量的内建拦截器完成了该框架的大部分操作。Struts 2的拦截器有如下两个特点:
Struts 2拦截器是可插拔式的设计,不管是否应用某个拦截器,对于Struts 2框架不会有任何影响;
Struts 2拦截器由struts-default.xml、struts.xml等配置文件进行管理,具有很大的可扩展性,开发者很容易扩展自己的拦截器。
在Sturts 2中的工作机制如下图所示。
在用户发出请求后,StrutsPrepareAndExecuteFilter会将其拦截,之后,大量的拦截器将会对该请求进行处理,最后才会调用相应的Action实例处理请求。
首先需要对拦截器进行定义,即为拦截器指定一个拦截器名。其最简单的格式如下:
为拦截器指定参数有两个时机:
定义拦截器时指定:这种参数值将作为默认参数值;
使用拦截器时指定:在配置Action时为拦截器参数指定值,这种方式会覆盖默认值。
在配置一个包是,还可以为其指定默认拦截器。一旦为某个包指定了默认拦截器,该包中所有未显式指定拦截器的Action,都会使默认拦截器起作用;而如果Action显式指定了拦截器,则该Action中,默认拦截器不起作用。
默认拦截器使用<default-interceptor-ref .../>元素进行配置,需要指定一个name属性,该name属性必须是一个已经存在的拦截器(栈)的名字。需要注意的是,每个包中只能有一个默认拦截器。
通过<interceptor-ref .../>元素可以在Action内使用拦截器。其配置格式如下:
开发自己的拦截器类,应该实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口需要实现三个方法:
init():在该拦截器被实例化之后,在该拦截器执行拦截之前,系统回调该方法。每个拦截器其init()方法只执行一次。
destroy():该方法与init()方法对应,在拦截器实例被小会之前,系统回调该方法。
intercept(ActionInvocation invocation):该方法是用户需要实现的拦截动作。其中,参数invocation包含了被拦截的Action的引用,可以调用该参数的invoke方法,将控制权转给下一个拦截器或者Action的execute方法。
除此之外,Struts 2还提供了AbstractInterceptor类,该类提供了init()和destroy()方法的空实现,继承这个类实现自定义拦截器会更简单。
拦截方法的拦截器
在默认情况下,如果为某个Action定义了拦截器,则这个拦截器会拦截该Action内的所有方法。但是在某些情况下,只需要拦截指定方法,此时就需要使用Struts 2拦截器的方法过滤特性。
实现方法过滤特性,需要继承MethodFilterInterceptor类。该类的intercept已经实现了对Action的拦截行为,但真正的拦截逻辑还需要开发者提供,也就是通过回调doIntercept方法实现。在MethodFilterInterceptor中,额外增加了两个方法:
public void setExcludeMethods(String excludeMethods):排除需要过滤的方法;
public void setIncludeMethods(String includeMethods):设置需要过滤的方法。
在使用该拦截器时,可以通过name属性为excludeMethods和includeMethods的<param .../>元素来指定不需要拦截和需要拦截的方法。
Struts 2拦截器是可插拔式的设计,不管是否应用某个拦截器,对于Struts 2框架不会有任何影响;
Struts 2拦截器由struts-default.xml、struts.xml等配置文件进行管理,具有很大的可扩展性,开发者很容易扩展自己的拦截器。
在Sturts 2中的工作机制如下图所示。
在用户发出请求后,StrutsPrepareAndExecuteFilter会将其拦截,之后,大量的拦截器将会对该请求进行处理,最后才会调用相应的Action实例处理请求。
一、拦截器的配置与使用
1. 配置拦截器
拦截器的配置主要是在struts.xml文件中进行的。首先需要对拦截器进行定义,即为拦截器指定一个拦截器名。其最简单的格式如下:
<interceptor name="拦截器名" class="拦截器实现类" />不过,在有些时候还需要在配置拦截器时传入参数,那么就需要在<interceptor .../>元素中使用<param .../>元素进行参数传入。其格式如下:
<interceptor name="拦截器名" class="拦截器实现类"> <!--prama元素可以出现0~无限多次--> <param name="参数名">参数值</param> </interceptor>除此之外,还可以将多个拦截器连在一起组成拦截器栈。拦截器栈使用<interceptor-stack .../>元素定义,同时在其中使用<interceptor-ref .../>来引用拦截器。其格式如下:
<interceptor-stack name="拦截器栈名"> <interceptor-ref name="拦截器名" /> <interceptor-ref name="拦截器名" /> <interceptor-ref name="拦截器名" /> ...... </interceptor-stack>从程序功能角度来讲,拦截器栈和拦截器的功能是统一的,可以将其看作是一个更大的拦截器。所以,在拦截器栈中,同样可以包含拦截器栈。
为拦截器指定参数有两个时机:
定义拦截器时指定:这种参数值将作为默认参数值;
使用拦截器时指定:在配置Action时为拦截器参数指定值,这种方式会覆盖默认值。
在配置一个包是,还可以为其指定默认拦截器。一旦为某个包指定了默认拦截器,该包中所有未显式指定拦截器的Action,都会使默认拦截器起作用;而如果Action显式指定了拦截器,则该Action中,默认拦截器不起作用。
默认拦截器使用<default-interceptor-ref .../>元素进行配置,需要指定一个name属性,该name属性必须是一个已经存在的拦截器(栈)的名字。需要注意的是,每个包中只能有一个默认拦截器。
2.使用拦截器
在定义了拦截器后,就可以使用这个拦截器或拦截器栈来拦截Action。拦截器的拦截行为会在Action的execute方法执行前被执行。通过<interceptor-ref .../>元素可以在Action内使用拦截器。其配置格式如下:
<interceptors> <interceptor name="first" class="..." /> <interceptor name="second" class="..." > <param name="...">value</param> </interceptor> ...... </interceptors> ...... <action name="..." class="..."> <result>...</result> ...... <interceptor-ref name="defaultStack" /> <interceptor-ref name="first" /> <interceptor-ref name="second" > <param name="...">value</param> </interceptor-ref> </action>其中,defaultStack是系统默认的拦截器栈。
二、自定义拦截器的实现
除了可以使用Struts 2的内建拦截器外,也可以使用自定义的拦截器来实现一些系统逻辑相关的通用功能。开发自己的拦截器类,应该实现com.opensymphony.xwork2.interceptor.Interceptor接口。该接口需要实现三个方法:
init():在该拦截器被实例化之后,在该拦截器执行拦截之前,系统回调该方法。每个拦截器其init()方法只执行一次。
destroy():该方法与init()方法对应,在拦截器实例被小会之前,系统回调该方法。
intercept(ActionInvocation invocation):该方法是用户需要实现的拦截动作。其中,参数invocation包含了被拦截的Action的引用,可以调用该参数的invoke方法,将控制权转给下一个拦截器或者Action的execute方法。
除此之外,Struts 2还提供了AbstractInterceptor类,该类提供了init()和destroy()方法的空实现,继承这个类实现自定义拦截器会更简单。
拦截方法的拦截器
在默认情况下,如果为某个Action定义了拦截器,则这个拦截器会拦截该Action内的所有方法。但是在某些情况下,只需要拦截指定方法,此时就需要使用Struts 2拦截器的方法过滤特性。
实现方法过滤特性,需要继承MethodFilterInterceptor类。该类的intercept已经实现了对Action的拦截行为,但真正的拦截逻辑还需要开发者提供,也就是通过回调doIntercept方法实现。在MethodFilterInterceptor中,额外增加了两个方法:
public void setExcludeMethods(String excludeMethods):排除需要过滤的方法;
public void setIncludeMethods(String includeMethods):设置需要过滤的方法。
在使用该拦截器时,可以通过name属性为excludeMethods和includeMethods的<param .../>元素来指定不需要拦截和需要拦截的方法。
相关文章推荐
- Android Studio 导入Eclipse Android的工程
- spring源码导入Eclipse火星版出现了问题
- 谈谈对Spring IOC的理解
- 谈谈对Spring IOC的理解
- Java的接口和抽象类详解
- java-第1个网页
- java后台获取cookie里面值得方法
- Eclipse自动补全代码
- java web如何获取项目的根路径
- 【44】java大数值剖析
- 【44】java大数值剖析
- 【44】java大数值剖析
- Java生成随机数
- 图解红黑树及Java进行红黑二叉树遍历的方法
- Java经典类库-Guava中的函数式编程讲解
- Java GC 调试手记
- java 环境变量 加入多个jar包
- 成为Java高手的25个学习要点(转)
- Java 中的堆和栈
- Eclipse汉化后发生错误,请参考日志文件。