Struts2即支持属性驱动,也支持模型驱动
属性驱动:在Action中提供与表单字段一一对应的属性,而后一一set赋值
模型驱动:使得表单字段都自动被set到一个JavaBean中,相似于Struts1.X的ActionForm
采用属性驱动的方式时,是由每一个属性来承载表单的字段值,运转在MVC流程里面
采用模型驱动的方式时,是由模型对象来承载全部的属性值,运转在MVC流程里面
若使用模型驱动方式的话,就必须单独提供一个JavaBean
可能与持久层打交道的JavaBean不太同样,所以极可能要对每一个对象提供两个JavaBean
好比Struts1的ActionForm,通常来讲绝对不会把ActionForm做为JavaBean跟持久层交互
ActionForm仅仅是联系Web和Action的一个桥梁,所以推荐使用属性驱动接收表单字段app
--------------------------------------------------------------------------------ide
在com.opensymphony.xwork2.ModelDriven接口源代码中有一段很重要的说明,现抄录以下
ModelDriven Actions provide a model object to be pushed onto the ValueStack in addition
to the Action itself,allowing a FormBean type approach like Struts
翻译:模型驱动的Action。将模型对象以及Action对象都放到ValueStack里面
容许像Struts同样的FormBean方式
也即:一个Action要想成为模型驱动的话,就必须实现ModelDriven接口
而咱们以前所一直继承的ActionSupport类并无实现ModelDriven接口
如下是采用模型驱动的Action代码示例
view plaincopy to clipboardprint?
public class ModelDrivenAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public User getModel() {
System.out.println(user);
return user;
}
public String execute() throws Exception {
System.out.println("Username is :" + user.getUsername());
System.out.println("Password is :" + user.getPassword());
return SUCCESS;
}
}
public class ModelDrivenAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public User getModel() {
System.out.println(user);
return user;
}
public String execute() throws Exception {
System.out.println("Username is :" + user.getUsername());
System.out.println("Password is :" + user.getPassword());
return SUCCESS;
}
} ModelDrivenAction类的执行流程是:首先调用getModel()方法获得User对象
接着根据JavaBean的原则将客户端传过来的属性,一个一个的set到User对象的属性中
将属性所有set完以后,再执行execute()方法。对于模型驱动,只要了解这些就足够了翻译
--------------------------------------------------------------------------------orm
模型驱动的底层实现机制
这里用到了defaultStack拦截器栈中的modelDriven拦截器
它对应com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor类,其API描述以下
public class ModelDrivenInterceptor extends AbstractInterceptor
Watches for ModelDriven actions and adds the action`s model on to the value stack.
翻译:观察模型驱动的Action,并将这个Action的模型【这里指User对象】放到值栈中
Note:The ModelDrivenInterceptor must come before the both StaticParametersInterceptor
and ParametersInterceptor if you want the parameters to be applied to the model.
翻译:若但愿将表单提交过来的参数应用到模型里面
那么ModelDrivenInterceptor拦截器就必须位于StaticParametersInterceptor和ParametersInterceptor拦截器前面
实际上struts-default.xml已完成这个工做了。能够在defaultStack拦截器栈中查看三者位置
因此对于采用模型驱动的方式的话,在struts.xml中只须要指定模型驱动的类就能够了
其它的都不须要咱们手工修改xml
--------------------------------------------------------------------------------对象
ModelDrivenInterceptor的部分源代码以下所示
view plaincopy to clipboardprint?
public class ModelDrivenInterceptor extends AbstractInterceptor{
public String intercept(ActionInvocation invocation) throws Exception{
Object action = invocation.getAction();
// 这个action就是当前拦截器准备拦截的Action对象
// 咱们这里的action就是ModelDrivenAction,它实现了ModelDriven<User>接口
// 根据多态性,可认为子类对象就是父类的一个实例,故action属于ModelDriven的实例
if(action instanceof ModelDriven){
// 将action强制转换为ModelDriven类型,得到ModelDriven的实例
ModelDriven modelDriven = (ModelDriven)action;
ValueStack stack = invocation.getStack();
// 调用getModel(),此时ModelDrivenAction中的getModel()才会被执行,得到User对象
Object model = modelDriven.getModel();
if(model != null){
// 得到User对象以后,就把它推入【压入】到值栈中,供后面调用
stack.push(model);
}
继承