Struts2的action解读

从职责上讲,Control层需要完成以下的职责:

1. 接收从Web容器传递过来的参数,并做恰当的类型转化

2. 调用逻辑处理

3. 搜集数据,并返回到视图

这个其中的第一步和第三步,都离不开Web容器中的对象的处理。而Struts2这个框架和传统框架区别之处在于Struts2中的Action,并不需要依赖于特定的Web容器。我们看不到类似HttpServletRequest,HttpServletResponse等Web容器相关的对象。

虽然Struts2的Action只是一个非常普通的Java对象,并不具备任何Web容器的特质,但是我们需要把Action放到一个更加大的环境中来看。事实上,Struts2为Action的执行,准备了完整的数据环境和执行环境。而这个执行环境,就保证了Action在Web容器中的顺利运行。

在Struts2中,每个Http的请求,会被发送到一个Filter。而这个Filter,就会针对每个请求,创建出一个代码的执行环境,并在这个基础上,为每个执行环境配备与之对应的数据环境,这个数据环境中的内容,就来自于Web容器中的一个又一个对象。这样,就能够顺利调用Action执行代码而无需担心它是否运行在Web容器中了。

数据环境就成为了Action获取Web容器的基础。所以,当Action需要获取Web容器的相关对象,需要通过数据环境来进行。

Struts2的Action的这一个重要特性,至少能为我们带来以下好处:

  1. 使得Struts2的Action非常易于测试

  如果我们完全不考虑Action的执行环境,仅仅把Action看作一个普通的Java对象,那么我们甚至可以直接new一个Action的对象,通过执行其中的方法完成测试。这样,我们就不需要任何的Mock,来模拟Web容器的环境。

  2. 结合Action的执行环境,使得Struts2在Control这个层次上,能够定义更加丰富的执行层次

因为Action是一个普通的Java类,而不是一个Servlet类,完全脱离于Web容器,所以我们就能够更加方便地对Control层进行合理的层次设计,从而抽象出许多公共的逻辑,并将这些逻辑脱离出Action对象本身。事实上,Struts2也正是这么做的,无论是Interceptor,还是Result,其实都是抽象出了Action中公共的逻辑部分,将他们放到了Action的外面,从而更加简化了Action的开发。

3. 使得Struts2的Action看上去更像一个POJO,从而更加易于管理

  Struts2的Action是一个线程安全的对象。而Web容器传递过来的参数,也会传递到Action中的成员变量中。这样,Action看上去就更像一个POJO,从而能够方便的被许多对象容器进行管理。比如说,你可以非常方便得把Action纳入到Spring的容器中进行管理。

Action的生命周期

Struts2的action解读

Action的五大元素:这些元素将涵盖Action的数据环境,Action的执行环境、Action的调度者、Action的层次结构和Action的执行结果。

ActionContext —— 数据环境

  之前我们提到了Struts2的Action并不是一个Servlet,它是脱离了Web容器的。但是对于一个Web框架来说,所有的数据请求(Request)和数据返回(Response)都来源于Web容器,那么Action在执行的时候,如何去获取这些数据呢?

 这个问题的答案就在于,我们需要为每个Action准备一个数据环境,这个数据环境被称之为:ActionContext。由于Action是应对于一个又一个的URL请求,所以ActionContext应该具备以下的特性:

  1. ActionContext应成为Action与Web容器之间的桥梁

  2. ActionContext中应该保存有针对某个请求的详细信息

  3. ActionContext应该是一个线程安全的类对象

Interceptor —— 丰富的层次结构

  简单回顾一下上面所提到的Action的职责,我们看到,需要在Action这个层面上完成的事情还不少。而完成这些职责,就需要我们对这些职责进行合理的分类和排序,将他们组织成有序的执行队列。在Struts2中,使用了一种类似责任链的设计模式对这些不同的职责进行分类并串联起来,从而使得Action层具备了丰富的层次结构。而在这个执行队列中的每个元素,就被我们称之为Interceptor,也就是拦截器。

Struts2的Interceptor,其拦截的对象是Action代码,可以定义在Action代码之前或者之后执行拦截器的代码。如果仔细留意一下Action LifeCycle图中的Interceptor和Action的部分,我们可以看到,Interceptor一层一层的把Action包了起来。这是一个典型的堆栈结构,在代码执行的时候,每个Interceptor不仅需要文成它自身的逻辑,还通过递归调用负责下一个拦截器或Action的调用。

Result —— 执行结果

  有执行就必然有执行的结果。在Struts2中,Action的执行结果被抽象成了一个层次。在这个层次中,可以定义任意类型的View层的结构。也就是说,Struts2并不强制View层的表现形式,可以是JSP、Freemarker模板、二进制流输出等等。

  Struts2把执行结果抽象成一个层次,使得你可以不再关注许多视图整合上面的细节,只需要考虑视图的类型和数据的准备,这样,你也可以不必在沉浸在杂乱的构造视图的代码中。

 

1.actionInvocation是什么

ActionInvocation就是Action的调用者。ActionInvocation在Action的执行过程中,负责Interceptor、Action和Result等一系列元素的调度。

2.ActionInvocation干什么

Interceptor通过ActionInvocation可以完全的改变Action行为:不让它执行、改变返回值、甚至可以细颗粒的操作Action的方法

你可能感兴趣的:(struts2)