论坛首页 Java企业应用论坛

纠正WebWork2的Model-driven(模型驱动)Action

浏览 34448 次
该帖已经被评为精华帖
作者 正文
   发表时间:2005-04-21  
引自《WebWork教程》
引用

另一类是Model-Driven(模型驱动的)Action
“它很像Struts的FormBean,但在WebWork中,只要普通Java对象就可以充当模型部分。
Model-Driven(模型驱动的)Action要求我们的Action实现com.opensymphony.xwork. ModelDriven接口,
它有一个方法:Object getModel();,我们用这个方法返回我们的模型对象就可以了。”

这个的解释是错误的!!

我们可以根据Action属性的不同将它分为两类:Field-Driven(字段驱动) Action和Model-Driven(模型驱动) Action。
一、Field-Driven(字段驱动)Action,Action拥有自己的属性,这些属性一般是Java的基本类型。表单字段直接和Action的属性 对应。
比如用户注册的Action:
RegisterAction.java
 public class RegisterAction implements Action{
 	private String userName;
 	private String password;
 	private String email;
 	
 	public String execute(); throws Exception{
 	//执行用户注册操作
 	}
 	......
 	get();/set();方法
 	..........
 	
 }
 
 页面register.html中会有:
 ......
 <input name="userName">
 .......

二、Model-Driven(模型驱动)Action,Action通过get方法暴露一个模型类,表单字段和模型类的属性对应。

Model-Driven概念与com.opensymphony.xwork.ModelDriven接口没有直接关系的。我们的Action不实现com.opensymphony.xwork.ModelDriven接口也有可能是Model-Driven。

例如:
User.java
 
 public class User{
 	private String userName;
 	private String password;
 	private String email;
 	......
 	get();/set();方法
 	..........
 }
 
 RegisterAction.java
 public class RegisterAction implements Action{
 	private User user = new User();;
 	
 	public String execute(); throws Exception{
 	//执行用户注册操作
 	}
 	public User getUser();{
 		return user;
 	}
 }
 
 
 页面register.html中会有:
 ......
 <input name="user.userName">
 .......

Model-Driven会通过OGNL的表达式语言来存取数据。例如:在注册时,表达式语言user.userName将会 执行getUser.setUserName()。

那com.opensymphony.xwork.ModelDriven接口又是做什么的呢?
  它会将Object getModel()取得的Model放到ValueStack中。可以理解为将这个Model的属性追加到Action中。它主要是作用是实现类似Struts的FormBean功能。

总结:如果将Model-Driven(模型驱动)Action认为是实现com.opensymphony.xwork.ModelDriven接口的观点是错误的,Model-Driven和com.opensymphony.xwork.ModelDriven接口并没有直接的关系。我们在实际应用中一般是将Model-Driven和Field-Driven结合在一起使用,并不需要将这两个概念完全区分开来。
   发表时间:2005-04-21  
没有看明白,好像是一样的。 

可以结合起来一起用? 也就是说即往Model里填充,也往Action里填充数据?

唉,太灵活也不好,以后都搞不清楚数据是怎么进来的。  
0 请登录后投票
   发表时间:2005-04-21  
moxie 写道
引自《WebWork教程》
引用

另一类是Model-Driven(模型驱动的)Action
“它很像Struts的FormBean,但在WebWork中,只要普通Java对象就可以充当模型部分。
Model-Driven(模型驱动的)Action要求我们的Action实现com.opensymphony.xwork. ModelDriven接口,
它有一个方法:Object getModel();,我们用这个方法返回我们的模型对象就可以了。”

这个的解释是错误的!!

我们可以根据Action属性的不同将它分为两类:Field-Driven(字段驱动) Action和Model-Driven(模型驱动) Action。
一、Field-Driven(字段驱动)Action,Action拥有自己的属性,这些属性一般是Java的基本类型。表单字段直接和Action的属性 对应。
比如用户注册的Action:
RegisterAction.java
 public class RegisterAction implements Action{
 	private String userName;
 	private String password;
 	private String email;
 	
 	public String execute(); throws Exception{
 	//执行用户注册操作
 	}
 	......
 	get();/set();方法
 	..........
 	
 }
 
 页面register.html中会有:
 ......
 <input name="userName">
 .......

二、Model-Driven(模型驱动)Action,Action通过get方法暴露一个模型类,表单字段和模型类的属性对应。
例如:
User.java
 
 public class User{
 	private String userName;
 	private String password;
 	private String email;
 	......
 	get();/set();方法
 	..........
 }
 
 RegisterAction.java
 public class RegisterAction implements Action{
 	private User user = new User();;
 	
 	public String execute(); throws Exception{
 	//执行用户注册操作
 	}
 	public User getUser();{
 		return user;
 	}
 }
 
 
 页面register.html中会有:
 ......
 <input name="user.userName">
 .......

Model-Driven会通过OGNL的表达式语言来存取数据。例如:在注册时,表达式语言user.userName将会 执行getUser.setUserName()。

那com.opensymphony.xwork.ModelDriven接口又是做什么的呢?
  它会将Object getModel()取得的Model放到ValueStack中。可以理解为将这个Model的属性追加到Action中。它主要是作用是实现类似Struts的FormBean功能。

总结:如果只是实现com.opensymphony.xwork.ModelDriven接口,就将Action当做是Model-Driven(模型驱动)Action的观点是错误的。我们在实际应用中一般是将Model-Driven和Field-Driven结合在一起使用。而com.opensymphony.xwork.ModelDriven接口一般很少会用到。


提出点疑问

首先,在使用Field-Driven(字段驱动)时也可以用Domain模型吧?
比如这样

public class RegisterAction implements Action{ 
        private User user;        
        public String execute(); throws Exception{ 
        //执行用户注册操作 
        } 
        ...... 
        get();/set();方法 
        .......... 
        
} 


在表单中可以

<input name="user.userName"> 


相对于Model-Driven(模型驱动)而言所做的变化也并不是太大,并且相应的属性也能够得到正确的填充
0 请登录后投票
   发表时间:2005-04-21  
好像不行吧。

我看ModelDrivenInterceptor里得判断是否是ModelDriven才决定如何做,否则要这个拦截器何用?
        if (action instanceof ModelDriven); {
            ModelDriven modelDriven = (ModelDriven); action;
            OgnlValueStack stack = invocation.getStack();;
            stack.push(modelDriven.getModel(););;
        }
0 请登录后投票
   发表时间:2005-04-21  
我试过可以的,OGNL可以自动的在<interceptor-ref name="params"/>中根据表单中user.userName这个field而在stack中转化为getUser().getUserName(),然后填充这个user的userName的属性的值
0 请登录后投票
   发表时间:2005-04-21  
rootsoso 写道

提出点疑问

首先,在使用Field-Driven(字段驱动)时也可以用Domain模型吧?
比如这样

public class RegisterAction implements Action{ 
        private User user;        
        public String execute(); throws Exception{ 
        //执行用户注册操作 
        } 
        ...... 
        get();/set();方法 
        .......... 
        
} 


如果你在Field-Driven(字段驱动)时也可以用Domain模型。那么你的Action即是Field-Driven也是Mode-Driven。

我这篇贴子主要是想说明“Mode-Driven (模型驱动的)Action这个概念和com.opensymphony.xwork.ModelDriven接口是没有直接关系的”
0 请登录后投票
   发表时间:2005-04-21  
说白了,实现了ModelDriven接口的Action,不仅在Action的成员变量中会有值,同时也会放到ValueStack里面去。
0 请登录后投票
   发表时间:2005-04-23  
我觉得夏昕的webworkguide中对驱动模式的描述更容易理解,也更合理。
0 请登录后投票
   发表时间:2005-04-25  
我认为是这样的:

1)moxie举的例子,还是属于Property-Driven
2)ModelDriven接口是ModelDriven的标志

但我们应该这么理解:
1)ModelDriven模式并不能从代码上为我们节省工作量,就如moxie举的例子而言,不用ModelDriven模式代码更少
2)ModelDriven模式实现了真正的MVC,结构更加清晰
0 请登录后投票
   发表时间:2005-04-25  
javacme 写道
我觉得夏昕的webworkguide中对驱动模式的描述更容易理解,也更合理。

但是这样的理解是错误的!我以前也是这样理解的,但后来我发现自己理解错了,所了就写了这篇文章。
引用

夏昕文档:
Webwork中,提供了两种Action驱动模式:
1. Property-Driven
2. Model-Driven
上面的示例中,我们应用了Model-Driven 的Action 驱动模式。对于这种模式,相信大
家已经比较熟悉。
下面介绍一下Property-Driven驱动模式。
Model-Driven 是通过Model 对象(上例中的LoginInfo)贯穿整个MVC 流程,而
Property-Driven,顾名思义, 是由Property(属性)作为贯穿MVC流程的信息携带者。
Property固然无法独立存在,它必须依附于一个对象。在Model-Driven模式中,实际上
这些属性被独立封装到了一个值对象,也就是所谓的Model。而Property-Driven中,属性将
依附在Action对象中。

你再仔细看看官方的说明:
引用

2 types of Actions possible:

Model-driven
Action has methods returning your model classes (myAction.getPet())
Fields in the view are fields of your model
Views refer directly to your model (property='pet.name')
Excellent because it allows model reuse

Field-driven
Action has fields of its own, which are fields in the view
execute() collates fields and interacts with the model
Views refer to action fields (property='name')
Useful where form is not parallel to model
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics