Struts2的结构为MVC模式,其中Action(动作)是Struts2中对应MVC的模型层。
一、Action的要求
Action可以是一个简单POJO(Plain Old Java Object),即不实现任何接口或不继承任何父类的普通Java类;也可以是实现了com.opensymphony.xwork2.Action接口的类;还可以是继承自com.opensymphony.xwork2.ActionSupport的类。只有一个需要注意的地方是,这个类必须要有一个名为execute的方法,且要求该方法访问权限为public,无参数,具有String类型的返回值。如下所示:
public String execute() throws Exception {
return "toWelcome";
}
二、Action中的内容
【1、页面字段】
Action可以用来接收来自页面请求中的字段,Struts2会自动将页面字段根据字段名与Action中的对应属性进行映射,并保存在Action中。
Action获取并保存页面请求中的字段的方式有两种:属性驱动 和 模型驱动。
【属性驱动】又分为两种:
一种是通过直接在Action中定义的属性来映射,在Action中写入与请求页面的字段同名的私有属性(private属性),并提供相应的setter/getter方法;
另一种是通过域对象的方式来映射,定义一个Model类,该类中写入与请求页面的字段同名的私有属性(private属性),并提供相应的setter/getter方法,同时在Action中定义一个Model类的私有属性,提供相应的setter/getter方法。这种方式要求请求页面在定义字段时,字段名称要用域对象名称作为前缀,例如在Model类如下:
public class WelcomeModel {
private String submitFlag = null;
public String getSubmitFlag() {
return submitFlag;
}
public void setSubmitFlag(String submitFlag) {
this.submitFlag = submitFlag;
}
}
Action中定义的域对象为:
private WelcomeModel wm = new WelcomeModel();
public WelcomeModel getWm(){
return wm;
}
public void setWm(WelcomeModel wm){
this.wm = wm;
}
则请求页面表单中如定义了字段需要与submitFlag进行映射,则此字段名应定义为wm.submitFlag,如下所示:
<input type="hidden" name="wm.submitFlag" value="login"/>
注意:
1、上面所述的Action中定义的属性,都是以private访问权限定义,也可以定义为public权限,当定义为public权限时,Action中对应的setter/getter方法就可以不必加入了;
2、所有与请求页面字段相对应的Action属性,或域对象,都需要初始化,由于基本类型的属性,在java编译运行时会自动初始化,所以不加入初始化语句也没有问题,但是如果是域对象这种用户类对象,及Integer这样的封装类型的对象,需要在属性声明的时候进行显式的初始化(new)。
3、另:在《研磨Struts2》一书中提到,如果是以属性驱动的第一种方式来映射,在Action中定义Integer类型的属性,被定义为public访问权限,没有setter/getter方法,当进行映射时会提示“无此属性(property)”错误。但是经过我测试(我使用的是struts2-core-2.3.16.jar),并未出现书中所述的问题,Struts正确的将页面请求中的字段映射到了Action中的对应属性。不知道是否是因为Struts2版本升级做了相应的支持。
【模型驱动】:
模型驱动与属性驱动第二种方式基本差不多,但是有以下几点区别:
1、Action要实现ModelDriven接口
ModelDriven接口要求类实现getModel方法,方法只需返回Action中声明的Model属性即可:
public Object getModel() {
return wm;
}
2、由于这里的wm属性并不是域对象,因此在请求页面中不需要加域对象的前缀,即:
<input type="hidden" name="submitFlag" value="login"/>
这几种字段映射方式可以同时在同一个Action中使用,由于域对象的方式在页面中指定了字段映射的域对象名及属性名,因此会优先进行映射,当属性驱动的第一种方式与模型驱动在属性名称上发生了冲突的时候,将优先为模型驱动方式的属性名称进行映射。
【2、业务逻辑】
execute()方法是用来实现业务逻辑的地方。但实际开发中,这里只是进行业务逻辑的调用,还有数据组装等。当业务逻辑执行完成后,execute()方法将返回一个字符串用以指定进行相应的页面(即MVC视图),这个字符串要与struts.xml文件中的配置一致。
【3、数据验证及其他】
当Action实现了com.opensymphony.xwork2.Validateable接口或继承自com.opensymphony.xwork2.ActionSupport类并重写validate()方法时,可以对页面数据进行验证,如果验证结果不满足要求,则Action将不会运行execute()方法,并跳转到struts.xml中对应Action-Mapping定义的"input"映射的页面,以此达到数据验证的目的。