1.Action是干什么的?翻译过来就是“动作”的意思...

传统的MVC框架中,Control层一般都是一个类似与Servlet的一个Java对象。因为从职责上讲,Control层需要完成以下的职责: 

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

2. 调用逻辑处理 

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

而在这个其中的第一步和第三步,都离不开Web容器中的对象的处理。 

 

2.struts2中Action

在Struts2中的Action,并不需要依赖于特定的Web容器。我们看不到类似HttpServletRequest,HttpServletResponse等Web容器相关的对象。 

这时候问题就出来了

         a.为什么Action只是一个普通的再也不能普通的类,并且不带任何的有关Web容器相关的对象,Action又是如何工作在Web容器中的?

又是如何与WEB进行通信并获取参数的?  

            Struts2为Action的执行,准备了完整的数据环境和执行环境。而这个执行环境,就保证了Action在Web容器中的顺利运行。 

      在Struts2中,每个Http的请求,会被发送到一个Filter。而这个Filter,就会针对每个请求,创建出一个代码的执行环境,并在这个基础上,

      为每个执行环境配备与之对应的数据环境,这个数据环境中的内容,就来自于Web容器中的一个又一个对象。这样,就能够顺利调用Action执行代码而无需担心

      它是否运行在   Web容器中了。 

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

         b.何为数据环境?何为执行环境?

             --ActionContext —— 数据环境 

              具备以下特性:

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

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

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

             --ActionProxy —— 执行环境

                         既然是执行环境,那么ActionProxy就需要提供Action执行的时候一切所需要的配置、参数等等,当然,也要有进行Action调用的入口。所以让我们来看一下ActionProxy的接口: 

 1 public interface ActionProxy {  
 2   
 3     /** 
 4      * Called after all dependencies are set 
 5      */  
 6     void prepare() throws Exception;  
 7       
 8     /** 
 9      * @return the Action instance for this Proxy 
10      */  
11     Object getAction();  
12   
13     /** 
14      * @return the alias name this ActionProxy is mapped to 
15      */  
16     String getActionName();  
17   
18     /** 
19      * @return the ActionConfig this ActionProxy is built from 
20      */  
21     ActionConfig getConfig();  
22   
23     /** 
24      * Sets whether this ActionProxy should also execute the Result after executing the Action 
25      * 
26      * @param executeResult 
27      */  
28     void setExecuteResult(boolean executeResult);  
29   
30     /** 
31      * @return the status of whether the ActionProxy is set to execute the Result after the Action is executed 
32      */  
33     boolean getExecuteResult();  
34   
35     /** 
36      * @return the ActionInvocation associated with this ActionProxy 
37      */  
38     ActionInvocation getInvocation();  
39   
40     /** 
41      * @return the namespace the ActionConfig for this ActionProxy is mapped to 
42      */  
43     String getNamespace();  
44   
45     /** 
46      * Execute this ActionProxy. This will set the ActionContext from the ActionInvocation into the ActionContext 
47      * ThreadLocal before invoking the ActionInvocation, then set the old ActionContext back into the ThreadLocal. 
48      * 
49      * @return the result code returned from executing the ActionInvocation 
50      * @throws Exception 
51      * @see ActionInvocation 
52      */  
53     String execute() throws Exception;  
54   
55     /** 
56      * Sets the method to execute for the action invocation. If no method is specified, the method provided by 
57      * in the action's configuration will be used. 
58      * 
59      * @param method the string name of the method to invoke 
60      */  
61     void setMethod(String method);  
62   
63     /** 
64      * Returns the method to execute, or null if no method has been specified (meaning "execute" will be invoked) 
65      */  
66     String getMethod();  
67       
68 }  

在这其中,prepare和execute方法是用作Action调用的入口函数,其他的接口定义都与Action执行时的运行参数和配置有关。 

3.实现Action类:

     Struts2不要求 Action类继承任何的Struts2的基类或实现Struts2接口。(但是,我们为了方便实现Action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并重写此类里的public String execute() throws Exception方法。

    Struts2中通常直接使用Action来封装HTTP请求参数,因 此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法。(当然,Action类中还可以封装处理结 果,把处理结果信息当作一属性,提供对应的getter和setter方法)

例如:

package org.caijieru.web.struts2.action;
 
import com.opensymphony.xwork2.ActionSupport;
 
/**
 *@authorcaijieru
 *@version1.0
 */
publicclass LoginAction extends ActionSupport{
    private String userName;
    private String password;
   
    private String msg; //结果信息属性
   
    /**
     *@returnthemsg
     */
    public String getMsg() {
        returnmsg;
    }
    /**
     *@parammsgthemsgtoset
     */
    publicvoid setMsg(String msg) {
        this.msg = msg;
    }
    /**
     *@returntheuserName
     */
    public String getUserName() {
        returnuserName;
    }
    /**
     *@paramuserNametheuserNametoset
     */
    publicvoid setUserName(String userName) {
        this.userName = userName;
    }
    /**
     *@returnthepassword
     */
    public String getPassword() {
        returnpassword;
    }
    /**
     *@parampasswordthepasswordtoset
     */
    publicvoid setPassword(String password) {
        this.password = password;
    }
   
    /**
     *处理用户请求的excute()方法
     *@return结果导航字符串
     *@throwsException
     */
    public String execute() throws Exception{
       if("test".equals(this.userName) &&
"test".equals(this.password)){
           msg = "登录成功,欢迎" + this.userName;
           returnthis.SUCCESS;
       }else{
           msg = "登录失败,用户名或密码错";
           returnthis.ERROR;
       }
    }
}

 

4.Action访问Servlet API

Struts2中的Action并没有和任何Servlet API耦合,这样框架更具灵活性,更易测试。
但是,对于web应用的控制器而言,不访问Servlet API几乎是不可能的,例如跟踪HTTP Session状态等。
例如:
public String execute() throws Exception{
        if("test".equals(this.userName) && "test".equals(this.password)){
            msg = "登录成功,欢迎" + this.userName;
            //获取ActionContext实例,通过它来访问Servlet API
            ActionContext context = ActionContext.getContext();
            //看session中是否已经存放了用户名,如果存放了:说明已经登录了;
//否则说明是第一次登录成功
            if(null != context.getSession().get("uName")){
                msg = this.userName + ":你已经登录过了!!!";
            }else{
                context.getSession().put("uName", this.userName);
            }
           
            returnthis.SUCCESS;
        }else{
            msg = "登录失败,用户名或密码错";
            returnthis.ERROR;
        }
    }

Struts2中通过ActionContext来访问Servlet API,让Action彻底从Servlet API 中分离出来,最大的好处就是可以脱离Web容器测试Action。

 

 

 
 posted on 2012-05-22 16:40  蔡傑儒  阅读(1258)  评论(0编辑  收藏  举报