- 浏览: 893442 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (687)
- java (127)
- servlet (38)
- struts (16)
- spring (22)
- hibernate (40)
- javascript (58)
- jquery (18)
- tomcat (51)
- 设计模式 (6)
- EJB (13)
- jsp (3)
- oracle (29)
- RUP (2)
- ajax (3)
- java内存管理 (4)
- java线程 (12)
- socket (13)
- path (5)
- XML (10)
- swing (2)
- UML (1)
- JBPM (2)
- 开发笔记 (45)
- Note参考 (15)
- JAXB (4)
- Quartz (2)
- 乱码 (2)
- CSS (2)
- Exception (4)
- Tools (7)
- sqlserver (3)
- DWR (7)
- Struts2 (47)
- WebService (2)
- 问题解决收藏 (7)
- JBOSS (7)
- cache (10)
- easyUI (19)
- jQuery Plugin (11)
- FreeMarker (6)
- Eclipse (2)
- Compass (2)
- JPA (1)
- WebLogic (1)
- powerdesigner (1)
- mybatis (1)
最新评论
-
bugyun:
受教了,谢谢
java 正则表达式 过滤html标签 -
xiongxingxing_123:
学习了,感谢了
java 正则表达式 过滤html标签 -
wanmeinange:
那如果无状态的。对同一个任务并发控制怎么做?比如继承Quart ...
quartz中参数misfireThreshold的详解 -
fanjieshanghai:
...
XPath 元素及属性查找 -
tianhandigeng:
还是没明白
quartz中参数misfireThreshold的详解
专栏地址:http://www.iteye.com/wiki/struts2/1379-action-in-struts2
多数的MVC框架中的Control层,都是一个Java对象。按照惯例,我们通常会把这个层次上面的Java对象统称为Action层。本篇文章,我们就来简单介绍一下Struts2中Action的相关内容。
Action的定义
传统的MVC框架中,Control层一般都是一个类似与Servlet的一个Java对象。因为从职责上讲,Control层需要完成以下的职责:
1. 接收从Web容器传递过来的参数,并做恰当的类型转化
2. 调用逻辑处理
3. 搜集数据,并返回到视图
而在这个其中的第一步和第三步,都离不开Web容器中的对象的处理。
Struts2中的Action,与其他传统的MVC框架不同,使用了XWork的Action来构造Control层。让我们首先来看看Action的接口定义:
- /**
- * All actions may implement this interface, which exposes
- * the execute() method. However, as of XWork 1.1, this is
- * not required and is only here to assist users. You are
- * free to create POJOs that honor the same contract
- * defined by this interface without actually implementing
- * the interface.
- */
- public interface Action {
- /**
- * Where the logic of the action is executed.
- *
- * @return a string representing the logical result of the execution.
- * See constants in this interface for a list of standard result values.
- * @throws Exception thrown if a system level exception occurs.
- * Application level exceptions should be handled by returning
- * an error value, such as Action.ERROR.
- */
- public String execute() throws Exception;
- }
/** * All actions may implement this interface, which exposes * the execute() method. However, as of XWork 1.1, this is * not required and is only here to assist users. You are * free to create POJOs that honor the same contract * defined by this interface without actually implementing * the interface. */ public interface Action { /** * Where the logic of the action is executed. * * @return a string representing the logical result of the execution. * See constants in this interface for a list of standard result values. * @throws Exception thrown if a system level exception occurs. * Application level exceptions should be handled by returning * an error value, such as Action.ERROR. */ public String execute() throws Exception; }
我们只需要实现这个接口,就可以在其中编写业务逻辑完成我们的功能。
- public class Index implements Action {
- private static final long serialVersionUID = -1070481751569420550L;
- /* (non-Javadoc)
- * @see com.opensymphony.xwork2.Action#execute()
- */
- public String execute() throws Exception {
- // write your logic here
- return SUCCESS;
- }
- }
public class Index implements Action { private static final long serialVersionUID = -1070481751569420550L; /* (non-Javadoc) * @see com.opensymphony.xwork2.Action#execute() */ public String execute() throws Exception { // write your logic here return SUCCESS; } }
在这个接口定义中,我们可以明显看到与传统的MVC框架之间的区别:Struts2中的Action,并不需要依赖于特定的Web容器。我们看不到类似HttpServletRequest,HttpServletResponse等Web容器相关的对象。
而这一点,也带来了问题:
提问:Struts2的Action并不带有任何Web容器相关的对象,Action又是如何工作在Web容器中的呢?
虽然Struts2的Action只是一个非常普通的Java对象,并不具备任何Web容器的特质,但是我们需要把Action放到一个更加大的环境中来看。事实上,Struts2为Action的执行,准备了完整的数据环境和执行环境。而这个执行环境,就保证了Action在Web容器中的顺利运行。
在Struts2中,每个Http的请求,会被发送到一个Filter。而这个Filter,就会针对每个请求,创建出一个代码的执行环境,并在这个基础上,为每个执行环境配备与之对应的数据环境,这个数据环境中的内容,就来自于Web容器中的一个又一个对象。这样,就能够顺利调用Action执行代码而无需担心它是否运行在Web容器中了。
至于这个执行环境和数据环境到底是什么,我们接下来会详细讲到。
提问:Struts2的Action并不带有任何Web容器相关的对象,Action中又如何与Web容器进行通信并获取Web容器的相关对象呢?
刚刚我们提到Struts2会为每个Http的请求建立一个执行环境和数据环境。其中,数据环境就成为了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的生命周期:
这张图来自于Struts2的Reference,我们能够在图中看到许多我们不熟悉的名词,比如ActionProxy,Interceptor等等。这些都是Struts2的Control层的重要元素,也是Struts2的Control层的一个层次化的体现。
上面的这张图基本上能够概括了Struts2的整个生命周期。接下来,我们就对Action中的一些重要元素进行简单的描述。
Action的五大元素
在大概了解了Struts2的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,也就是拦截器。
拦截器是AOP中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用。正如上面Struts2的Reference中讲述的,Struts2的Interceptor,其拦截的对象是Action代码,可以定义在Action代码之前或者之后执行拦截器的代码。
如果仔细留意一下Action LifeCycle图中的Interceptor和Action的部分,我们可以看到,Interceptor一层一层的把Action包了起来。这是一个典型的堆栈结构,在代码执行的时候,每个Interceptor不仅需要文成它自身的逻辑,还通过递归调用负责下一个拦截器或Action的调用。
也正如Struts2的Reference所说,Struts2提供的绝大多数的功能支持,都通过Interceptor来实现,这些Interceptor可以随意进行配置,并且能够方便的插入到程序中去运行。
Result —— 执行结果
有执行就必然有执行的结果。在Struts2中,Action的执行结果被抽象成了一个层次。在这个层次中,可以定义任意类型的View层的结构。也就是说,Struts2并不强制View层的表现形式,可以是JSP、Freemarker模板、二进制流输出等等。
Struts2把执行结果抽象成一个层次,使得你可以不再关注许多视图整合上面的细节,只需要考虑视图的类型和数据的准备,这样,你也可以不必在沉浸在杂乱的构造视图的代码中。
ActionProxy —— 执行环境
有了拦截器Interceptor,有了Action本身,也有了Action的执行结果Result,我们就需要一个类似调度器的产品,将这些元素整合起来,进行调度执行。在上面的Action Lifecyle的图中,我们可以看到,Interceptor、Action和Result都处于ActionProxy中,所以ActionProxy就成为了所有这些元素的执行环境。
既然是执行环境,那么ActionProxy就需要提供Action执行的时候一切所需要的配置、参数等等,当然,也要有进行Action调用的入口。所以让我们来看一下ActionProxy的接口:
- public interface ActionProxy {
- /**
- * Called after all dependencies are set
- */
- void prepare() throws Exception;
- /**
- * @return the Action instance for this Proxy
- */
- Object getAction();
- /**
- * @return the alias name this ActionProxy is mapped to
- */
- String getActionName();
- /**
- * @return the ActionConfig this ActionProxy is built from
- */
- ActionConfig getConfig();
- /**
- * Sets whether this ActionProxy should also execute the Result after executing the Action
- *
- * @param executeResult
- */
- void setExecuteResult(boolean executeResult);
- /**
- * @return the status of whether the ActionProxy is set to execute the Result after the Action is executed
- */
- boolean getExecuteResult();
- /**
- * @return the ActionInvocation associated with this ActionProxy
- */
- ActionInvocation getInvocation();
- /**
- * @return the namespace the ActionConfig for this ActionProxy is mapped to
- */
- String getNamespace();
- /**
- * Execute this ActionProxy. This will set the ActionContext from the ActionInvocation into the ActionContext
- * ThreadLocal before invoking the ActionInvocation, then set the old ActionContext back into the ThreadLocal.
- *
- * @return the result code returned from executing the ActionInvocation
- * @throws Exception
- * @see ActionInvocation
- */
- String execute() throws Exception;
- /**
- * Sets the method to execute for the action invocation. If no method is specified, the method provided by
- * in the action's configuration will be used.
- *
- * @param method the string name of the method to invoke
- */
- void setMethod(String method);
- /**
- * Returns the method to execute, or null if no method has been specified (meaning "execute" will be invoked)
- */
- String getMethod();
- }
public interface ActionProxy { /** * Called after all dependencies are set */ void prepare() throws Exception; /** * @return the Action instance for this Proxy */ Object getAction(); /** * @return the alias name this ActionProxy is mapped to */ String getActionName(); /** * @return the ActionConfig this ActionProxy is built from */ ActionConfig getConfig(); /** * Sets whether this ActionProxy should also execute the Result after executing the Action * * @param executeResult */ void setExecuteResult(boolean executeResult); /** * @return the status of whether the ActionProxy is set to execute the Result after the Action is executed */ boolean getExecuteResult(); /** * @return the ActionInvocation associated with this ActionProxy */ ActionInvocation getInvocation(); /** * @return the namespace the ActionConfig for this ActionProxy is mapped to */ String getNamespace(); /** * Execute this ActionProxy. This will set the ActionContext from the ActionInvocation into the ActionContext * ThreadLocal before invoking the ActionInvocation, then set the old ActionContext back into the ThreadLocal. * * @return the result code returned from executing the ActionInvocation * @throws Exception * @see ActionInvocation */ String execute() throws Exception; /** * Sets the method to execute for the action invocation. If no method is specified, the method provided by * in the action's configuration will be used. * * @param method the string name of the method to invoke */ void setMethod(String method); /** * Returns the method to execute, or null if no method has been specified (meaning "execute" will be invoked) */ String getMethod(); }
很显然,在这其中,prepare和execute方法是用作Action调用的入口函数,其他的接口定义都与Action执行时的运行参数和配置有关。
ActionInvocation —— 调度者
在上面的ActionProxy的接口定义中,我们可以看到有一个比较特殊的变量:ActionInvocation比较吸引我们的眼球。从字面上去理解,ActionInvocation就是Action的调用者。事实上也是如此,ActionInvocation在这个Action的执行过程中,负责Interceptor、Action和Result等一系列元素的调度。
在之后的章节中,这个ActionInvocation类也将成为我们解读Struts2源码的一个重要入手点。这个类将告诉你,Struts2是如何通过ActionInvocation来实现对Interceptor、Action和Result的合理调度的。
发表评论
-
ognl表达式
2011-07-07 00:36 1301OGNL是Object Graphic Navigation ... -
在Struts 2_0中实现表单数据校验
2011-07-07 00:02 1147转换与校验(Conversion & Validati ... -
简单的struts2输入校验框架
2011-05-13 23:43 10901.输入页面login.jsp: <%@ page ... -
struts2在学习(十二)--表单验证的两种方式
2011-05-13 23:13 960第四个示例:注解方式校验器---用户注册页面user2_reg ... -
struts2在学习(十一)--表单验证的两种方式
2011-05-13 23:09 909第二个示例:XML配置式校验器---登录和注册页面user_l ... -
struts2在学习(十)--表单验证的两种方式
2011-05-13 22:56 11661. Struts2中的输入校验2. 编码方式校验 1) A ... -
struts2采用convention-plugin实现零配置
2011-05-13 21:58 1120最近开始关注struts2的新特性,从这个版本开始,Strut ... -
基于SSH2框架Struts2拦截器的登录验证实现
2011-04-01 22:00 2293通过之前的Struts2.1.6+Spring2.5.6+H ... -
通过ActionContext类访问Servlet对象
2011-04-01 21:40 1924ActionContext类位于com.opensympho ... -
webwork 之销毁session
2011-04-01 17:35 1773销毁的意思?不是清空 ... -
Struts2 Convention Plugin(三)
2011-03-18 01:26 1206Annotation 参考Convention使用某些注解语句 ... -
Struts2 Convention Plugin(二)
2011-03-18 01:25 1155Results and result codesStruts ... -
Struts2 Convention Plugin(一)
2011-03-18 01:25 1105Introduction从struts2.1版本开始,Conv ... -
struts2页面中的标签调用类的方法
2011-03-15 16:33 1624<s:set name="str" ... -
Apache Struts 2.2.1 GA版发布
2011-03-14 17:14 1339昨日,Apache软件基金会发布了Struts 2.2.1 G ... -
spring2 +hibernate 3 + struts 配置
2011-03-14 15:15 12191. web.xml 1. <?xml versi ... -
Struts2 中action之间的跳转
2011-03-14 12:32 1258转载于http://zhou568xiao.iteye.com ... -
Struts2 的Result Type
2011-03-13 16:35 1050http://www.blogjava.net/duanzhi ... -
struts2 跳转类型 result type=chain、dispatcher、redirect(redirect-action)
2011-03-13 16:32 1627dispatcher 为默认跳转类型,用于返回一个视图资源(如 ... -
struts2防止重复提交
2011-03-10 23:07 1296struts2的防止重复提交 也使用到了 token (令牌机 ...
相关推荐
在Action类的设计上,Struts1要求Action类继承抽象基类,而在Struts2中,Action类可以选择实现Action接口或其他接口,也可以直接使用任何具有`execute`方法的POJO对象,提供了更大的灵活性。此外,Struts2的Action...
- 在`web.xml`中配置`ActionServlet`这个控制器,确保所有用户请求都能被Struts2框架接收并处理。 #### 三、Struts2的关键特性 **1. 校验框架**: - Struts2提供了强大的校验功能,可以轻松实现数据验证,提高应用...
2. **Action与Result**:在Struts2中,Action类是处理用户请求的核心,它封装了业务逻辑并决定响应的结果。Result则定义了请求处理后的输出,可以是重定向、转发到某个JSP页面或者其他HTTP响应。 3. **配置文件**:...
5. **Interceptor(拦截器)**:拦截器是Struts2的一大特色,它允许开发者在Action执行前后插入自定义逻辑,实现如日志记录、权限验证等功能。 接下来,我们开始搭建Struts2的开发环境: 1. **环境准备**:确保你...
《跟我学Spring3》这本书详细介绍了Spring框架在多个方面的应用,包括ORM支持、事务管理和Web框架集成等。以下是对这些章节内容的详细说明: 【第八章】 对ORM的支持: 1. **8.1 概述**:ORM(Object-Relational ...
《跟我学Spring3》这本书详细介绍了Spring框架与各种ORM(对象关系映射)框架的集成,以及Spring的事务管理和Web框架集成。以下是其中关键知识点的深入解析: **8. ORM支持** 1. **8.1 概述**:ORM允许开发者以面向...
《跟我学Spring3-源码》教程是一份深入解析Spring框架3.x版本核心源码的教育资源,适合对Java和J2EE技术有一定基础的开发者学习。本教程旨在帮助读者理解Spring框架的工作原理,提高在实际项目中的应用能力。通过...
"跟我学Java Web的PPT"是一份宝贵的教育资源,适合初学者和有经验的开发者用来提升自己的技能。这份PPT可能涵盖了从基础概念到高级技术的全方位讲解,帮助你构建完整的Java Web知识体系。 在Java Web开发中,核心...
- **集成Struts1.x和Struts2.x**:通过Spring的`Action`和`ActionForm`等组件实现与Struts的集成。 - **集成JSF**:通过Spring的JSF集成支持,利用`ManagedBean`等特性与JSF组件交互。 ### 四、零配置 #### 1.17 ...
3. **配置文件**:Struts使用struts-config.xml或struts2的struts.xml配置文件,定义Action类、ActionForm、结果页面等,以及它们之间的映射关系。 4. **Interceptor拦截器**:Struts2引入了拦截器,可以实现请求...
实践中,开发者需要创建数据库表,编写DAO(数据访问对象)和Service层接口及实现,编写Struts2 Action,最后进行单元测试和功能测试,确保系统正常运行。 通过这个教程,学习者不仅可以掌握SSH框架的集成技术,还...
Struts的工作原理,如下图2所示: <br/> 控制:通过图2大家可以看到有一个XML文件Struts-config.xml,与之相关联的是Controller,在Struts中,承担MVC中Controller角色的是一个Servlet,叫ActionServlet...
《跟我学Spring3》这本书是针对Spring框架的深入学习指南,涵盖了多个关键章节,包括Spring对ORM(对象关系映射)的支持、事务管理和与其他Web框架的集成等内容。以下是各章节主要内容的详细阐述: 1. **第八章:对...
《跟我学Spring3》是一本全面介绍Spring框架的教程,主要涵盖了Spring对ORM支持、事务管理以及与其他Web框架的集成等内容。以下是对其中关键知识点的详细解析: 1. **Spring对ORM的支持**: - **8.1 概述**:这...
标题“补跟我一起写大虾网(第1天源码)”和描述中提到的“博文链接:https://yulon.iteye.com/blog/588083”表明这是一个关于编程学习的系列教程,作者可能正在引导读者逐步了解并编写一个名为“大虾网”的项目。...
6. **跟我学Spring教程**:这可能是一份学习资料,涵盖了Spring框架的基础知识、核心概念,如依赖注入、AOP、MVC等,以及如何在实际项目中使用Spring。 7. **Hibernate3.2核心包的作用**:Hibernate 3.2版本包含了...
《跟我学Spring3》是一本全面介绍Spring框架的教程,主要涵盖了Spring对ORM支持、事务管理、Web框架集成以及SSH集成开发等多个方面。Spring作为Java领域最流行的应用框架之一,其强大的功能和灵活性使得它在企业级...
通过这次的毕业设计,我发现好多学到的东西都用到了,譬如软件工程、软件测试、 JAVA 、 J2EE 、数据库等课程。在这段时间里,我到图书馆查找了很多关于 J2EE 的书籍。使我更加了解 JSP 界面,以及 MVC 框架。 ...