struts2重要知识点总结(1):

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013730093/article/details/50277651

struts2最近又看了一边,每看一次都有一次的收获,这里总结struts2中的一些重要的知识点:
action介绍:
1:action类代表着一次请求或者调用,每个请求的动作都对应一个相应的action类,action是一个独立的工作单元
2:struts2中action充当着MVC中模型的角色,但是实际中其实action处理的是逻辑部分,和dispatcher共同担任了MVC中controler的角色,不同的是dispatcher担任的是业务部分
3:在struts2中,action可以不实现任何特殊的接口或者继承特殊的类,仅仅看成是一个pojo类,但是还有一个空参的execute方法
4:实现Action类,这个类中主要定义了一些常量

public abstract interface com.opensymphony.xwork2.Action {

  // Field descriptor #4 Ljava/lang/String;
  public static final java.lang.String SUCCESS = "success";

  // Field descriptor #4 Ljava/lang/String;
  public static final java.lang.String NONE = "none";

  // Field descriptor #4 Ljava/lang/String;
  public static final java.lang.String ERROR = "error";

  // Field descriptor #4 Ljava/lang/String;
  public static final java.lang.String INPUT = "input";

  // Field descriptor #4 Ljava/lang/String;
  public static final java.lang.String LOGIN = "login";

  // Method descriptor #16 ()Ljava/lang/String;
  public abstract java.lang.String execute() throws java.lang.Exception;
}

5:继承ActionSupport类,由于ActionSupport本身实现了Action接口,所以继承ActionSupport实际上就是相当于实现了Action接口,自定义的Action类继承了ActionSupport类的时候,通常需要重写execute()方法
6:ActionSupport类还实现了几个其他的接口,提供了更多的功能
#: com.opensymphony.xwork2.Validateable:提供validate()方法来为Action增加验证的功能
#: com.opensymphony.xwork2.Validateaware:提供方法来保存和恢复action或field级的错误信息
#: com.opensymphony.xwork2.TextProvider:提供获取本地信息文本的功能
#: com.opensymphony.xwork2.LocaleProvider:提供getLocale()方法来获取本地消息
7:execute方法的内部实现方式
execute方法在实际的开发中通常需要做下面的事情
7.1:收集用户传递过来的数据
7.2:把用户收集的数据组织成逻辑层需要的类型和格式
7.3:调用逻辑层接口,来执行业务逻辑处理
7.4:准备下一个页面中所需要展示的数据,存放在相应的地方
7.5:转向下一个页面

        1.  public class HelloWorldAction extends ActionSupport {  
2.      private String account;  
3.      private String password;  
4.      private String submitFlag;  
5.        
6.      public String execute() throws Exception {  
7.          //收集参数 ,一般使用的是HttpServletRequest,一般只要页面中元素的名称和action中的属性相对应,会通过param拦截器自动的注入的 
8.          //组织参数  一般是数据组织成逻辑层的类型或格式就可以了
9.          //调用逻辑层来进行逻辑处理,businessExecute方法中一般执行的是与数据库操作相关的  
10.         this.businessExecute();  
11.         //准备下一个页面所需要的数据  ,例如向跳转的中,显示XXX,你已登陆成功
12.         //转向下一个页面,通过返回的result来告知跳到那个jsp页面或者action中的某个方法  
13.         return "toWelcome";  
14.     }  

8:action中的数据来源
在struts2中,页面中的数据和action中的属性,有两种基本的对应方式,分别是,属性驱动(filedDriven)和模型驱动(ModelDriven)
属性驱动的两种情况:
1:基本类型的属性对应
2:javaBean风格的属性对应**
基本类型的属性驱动:
就是web页面中要提交的html控件的name属性,和action属性或者属性对应的getter/setter相对应,这种做法就是基本类型的属性对应的属性驱动(有点绕口,哈哈)
比如在登陆界面中这样写:

    <form action="XXX" method="post">
        <input type="text" name="userName"/><br/>
        <input type="text"  name="gender"/><br/>
        <input type="submit" value="提交"/>
    </form>

在action中是这样写的:

public class Demo extends ActionSupport{
    //和页面上的input控件中的userName,以及gender相对应,并生成setter和gerter方法
    //Ctrl + Alt +s 快速的找到生成个getter 和 setter方法
    private String userName;
    private String gender;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
}

这里的action中的userName 和 gender都是private 外界是不能访问的,所以生成setter/getter方法来设置值,当然你如果觉得为每个属性提供getter/setter方法比较累赘,那么你只需把userName和gender方法设置成public就可以了,但是一般不建议属性直接对外部开放

属性驱动(filedDriven):
如果action中的属性比较多,那么setter/getter方法将会特别多,造成代码特别的凌乱,我们可以把有相关联系的单独的提取出来做成一个javaBean类,例如刚才的userName和gender可以提成一个user对象中的属性
User.java

package javaBean;
public class User {
    private String userName;
    private String gender;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
}

新的action中Demo.action

public class Demo extends ActionSupport{
    private User user= new User();
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

当然了jsp也没中也要有相应的改动:

<form action="XXX" method="post">
        <input type="text" name="User.userName"/><br/>
        <input type="text"  name="User.gender"/><br/>
        <input type="submit" value="提交"/>
    </form>

模型驱动ModelDriven:
struts2中海油另外的一种数据对应的方式叫做模型驱动,基本实现是让action实现一个ModelDriver的接口,这个接口需要我们实现一个genModel的方法,这个方法的返回值就是action所使用的数据模型对象
把刚才action中的代码修改成ModelDriven的实现方式,只是添加了ModelDriven的实现,另外去掉了Userde 的setter/getter方法,其他的基本不变

public class Demo extends ActionSupport implements ModelDriven{
    private User user= new User();
    public Object getModel(){
        return user;
    }
}

当然jsp页面中也许做一点改动的:

<form action="XXX" method="post">
        <input type="text" name="userName"/><br/>
        <input type="text"  name="gender"/><br/>
        <input type="submit" value="提交"/>
    </form>
<!-- 去掉user这个前缀 ,因为一个action对应一个model,如果加上前缀,反而找不到属性了-->

到底该用哪个对应方式呢:
属性驱动(基本数据类型的属性对应),比较凌乱,对于属性比较少的只有一两个可以使用
javaBean属性对应,优先推荐这个
模型驱动:
这三种方式是可以混合使用的,甚至是三种方式可以一起使用,但是属性驱动(基本数据类型的属性)和模型驱动有可能发生冲突,因为都不带前缀,如果出现这种冲突的情况,那么优先模型驱动的对应方式。

Action的生命周期
Struts2的Action的生命周期是:Struts2为每个请求都重新初始化一个Action的实例。可以稍微改造一下代码来验证一下。
1:给HelloWorldAction加上一个public无参的构造方法,在里面输出一句话。
大家都知道,一个Java类如果没有写构造方法,那么会有一个默认的public无参的构造方法,这里只是把它明确的写出来了,因此这么做,并没有改变Action的任何功能,只是想看一下到底什么时候,Action会被初始化。示例代码如下:

1.  public LoginAction (){  
2.      System.out.println("LoginAction被初始化");  
3.  }

2:然后在execute方法上也加入一个打印Action自己这个对象实例的语句,示例代码如下:

1.  public String execute() throws Exception {  
2.      System.out.println(this);  
3.      this.businessExecute();  
4.      return "toWelcome";  
5.  }

在打印一个对象实例的时候,实际上是调用的这个类的toString方法,但是LoginAction类没有实现toString方法,所以,会调用到Object的toString方法。Object的toString方法会打印出自己的全类名和Object的hashcode方法的返回值,这个hashcode方法返回一个数字,只要这个数字不同,则被打印的对象就绝不是同一个对象。
修改做完之后,重新启动Tomcat,仔细察看后台的输出信息,你会发现启动的时候,并没有打印出来那句“LoginAction被初始化”,这说明了Action的初始化并不是在Tomcat启动的时候进行的。
我们提交表单并刷新再次提交,大家观察console上的输出。
“LoginAction被初始化”这句话被打印了两次,说明LoginAction对象的构造方法被调用了两次。
而且两次打印的toString分别是“login.LoginAction@922804”和“login.Login@18e8541”,这说明了为两次web请求服务的LoginAction对象不是同一个。
因此请记住,Struts2中的Action在每一次web请求的时候都要新建一个实例。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页