您的位置:首页 > 编程语言 > Java开发

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实例处理请求。

  

一、拦截器的配置与使用

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 .../>元素来指定不需要拦截和需要拦截的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: