多数的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.
- *
- * a string representing the logical result of the execution.
- * See constants in this interface for a list of standard result values.
- * 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)
- * com.opensymphony.xwork2.Action#execute()
- */
- public String execute() throws Exception {
- // write your logic here
- return SUCCESS;
- }
- }
Struts2 Reference 写道
Interceptors can execute code before and after an Action is invoked.
拦截器是AOP中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用。正如上面Struts2的Reference中讲述的,Struts2的Interceptor,其拦截的对象是Action代码,可以定义在Action代码之前或者之后执行拦截器的代码。 如果仔细留意一下Action LifeCycle图中的Interceptor和Action的部分,我们可以看到,Interceptor一层一层的把Action包了起来。这是一个典型的堆栈结构,在代码执行的时候,每个Interceptor不仅需要文成它自身的逻辑,还通过递归调用负责下一个拦截器或Action的调用。 Struts2 Reference 写道
Most of the framework's core functionality is implemented as Interceptors. Features like double-submit guards, type conversion, object population, validation, file upload, page preparation, and more, are all implemented with the help of Interceptors. Each and every Interceptor is pluggable, so you can decide exactly which features an Action needs to support.
也正如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;
- /**
- * the Action instance for this Proxy
- */
- Object getAction();
- /**
- * 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();
- }