struts2框架(三)——拦截器

来源:互联网 发布:伊朗美女 知乎 编辑:程序博客网 时间:2024/05/16 03:35

拦截器

工作原理

在Struts2动作的调用是一个分层的的过程,总是包含一系列的拦截器在动作执行之前或之后执行。框架不直接调用动作的execute()方法,而是创作一个叫做ActionInvocation的对象,它封装了动作和一系列被配置在动作执行之前或之后触发的拦截器。图3-1展示了ActionInvocation类封装的完整的动作执行过程。


图3-1 ActionInvocation 封装了动作及与之关联的拦截器和结果的执行

  在struts-default包的defaultStack中了大量的内建拦截器,能帮助框架完成大部分的处理工作。图中我们提供了default-Stack的简化版本。一个常见的工作流过程:

1.没有一个拦截器中断调用;

2.动作最终会执行并返回一个控制字符串来选择合适的结果;

3.在结果执行之后,按照反序每一个拦截器在做一些后加工的工作。

拦截器有时候可以决定动作不应执行。在这种情况下,拦截器可以自己返回一个控制字符串从而终止工作流。例如workflow拦截器,它做两件事:

1.调用实现了Validateable接口的动作中的validate()方法;(ActionSupport类实现了该接口,所以继承ActionSupport类的动作拥有此方法)

2.检查动作是否出现了错误信息。如果有错误信息,则返回“input”终止后续执行。

总指挥ActionInvocation

ActionInvocation类指挥动作的完整执行,以及与之相关的拦截器栈的顺序触发。当框架收到一个URL请求时,它首先决定这个URL映射到那个动作,这个动作的一个实例会被加入到一个新创建的ActionInvocation示例中。接着框架咨询声明性架构(应用程序的xml或者java注解创建),以发现那些拦截器应该触发,以及按什么顺序触发。

触发过程

ActionInvocation公开了invoke()方法。每个拦截器都有一个public Stringintercept(ActionInvocation invocation)方法。此方法是拦截器执行的入口点。

拦截器执行周期:

 1)做一些预处理;

2)通过调用invoke()方法(在intercept方法中调用参数invocation中的invoke())将控制转移给后续的拦截器,最后直到动作,或者通过返回一个控制字符串终止执行;

3)做一些后加工。

TimerInterceptor拦截器记录动作执行花费的时间。如下图TimerInterceptor的interccept()方法:


图2 timerInterceprot 的intercept()

说明:    1.拦截器的预处理阶段——记录开始时间

2.调用invoke()控制转移给下一个拦截器

3.后加工——计算了动作执行经过的时间

这个触发过程可以看成是个递归过程。框架通过第一次调用ActionInvocation对象的invoke(),并将ActionInvocation的对象传入到拦截器栈中的第一个拦截器的intercept()方法中。然后在拦截器中通过调用invoke()来触发后面的拦截器,或像workflow那样在验证不通过时直接返回错误控制字符串来终止工作流,这样就不去调用invoke()去转交控制(即触发后续的拦截器),直接递归返回。

内建的拦截器

defaultStack中声明了一系列的拦截器,顺序很重要。可以通过扩展struts-default包来继承这个栈。这里只列举了一部分。

 工具拦截器

  timer——记录执行花费时间

  logger——一个简单的日志记录机制

数据转移拦截器

params——将请求的参数转移到通过ValueStack公开的属性上。

static-params——在params之前触发,作用是将定义在声明性架构动作元素中的参数转移到ValueStack公开的属性上。

fileUpload——用于文件上传

工作流拦截器

1 workflow

workflow拦截器与动作协作,提供数据验证以及错误发生时改变后续工作流的功能。它做两件事:

1)调用实现了Validateable接口的动作中的validate()方法;(ActionSupport类实现了该接口,所以继承ActionSupport类的动作拥有此方法)

2)检查动作是否出现了错误信息。如果有错误信息,则返回“input”终止后续执行。下图是Interceprot执行过程:



 说明:   1)获取action实例

2)检查此action是否实现了Validateable接口,如果实现了此接口,动作调用validate()方法执行验证逻辑。

3)检查Action是否实现ValidationAware接口

4)通过调用hasErrors()来确认验证逻辑是否产生了错误信息。


2 validation

validation拦截器是 struts2验证框架的一部分,提供了声明性的方式验证你的数据。不编写验证代码,验证框架让你使用xml或java注解描述数据的验证规则。(这里需要使用框架提供的验证器,在验证框架部分我会详细说明,暂时知道这些就可以)这里要区别用 Validateable接口验证的方式。   Validateable接口提供了一种编程式的验证机制。把验证的代码放在validate()中,它会被workflow拦截器执行。

注意:validation拦截器要放在workflow之前触发,在defaultStack中处理。


声明拦截器

拦截器与拦截器栈

struts-default.xml文件中struts-default包的部分拦截器的声明如图3-5:

图3-5 struts-default包拦截器声明

interceptors包含所有的interceptor和interceptor-stack的声明。每个interceptor有个引用名,interceptor-stack通过引用名将拦截器放入栈中,栈很方便的将拦截器分类,方便管理。

将拦截器映射到动作组件

i nterceptor-ref元素可以完成拦截器和动作的关联。


 设置、覆盖拦截器参数

    很多拦截器接受参数,可以使用interceptor-ref元素向他们传入参数。(这里参数的详细应用我后面会将,暂时知道可以这么用参数就可以了)

 这里的excludeMethods指workflow拦截器不应执行的方法名。


覆盖了workflow拦截器的excludeMethods参数。

构建自定义的拦截器

 实现interceptor接口

真正的业务逻辑在intercept()中,这个方法被递归的invocation.invoke()调用。

构建AuthenticationInterceptor拦截器

拦截器处理三阶段——预处理、调用ActionInvocation.invoke() 、后加工。AuthenticationInterceptor拦截器的工作过程:当一个请求访问一个安全的动作时,在预处理阶段检查此请求是否是一个通过身份验证的用户发出的。如果用户已经通过身份验证(比如是已经登录的用户),拦截器调用invoke()方法,转移控制;如果用户没有通过身份验证,拦截器返回一个控制字符串,终止之后的执行,控制字符串将用户带到登录界面。


   这里通过验证的用户被保存到会话映射中。




注意:拦截器实例在动作之间共享。虽然每个请求都会创建动作的一个新实例,但是拦截器会重用。拦截器是无状态的,不要在拦截器中存储与当前正在处理的请求相关的数据


原创粉丝点击