在以往的web开发中,如果要在表单显示什么内容,我们就需要在Action中提前定义好表单显示的所有属性,以及一系列的get和set方法。如果实体类的属性非常多,那么Action中也要定义相同的属性。在Struts2中,ModelDriven模型驱动就提供了另一种方式,减少了重复性的代码。
下面我们就来具体看看在项目中如何使用:
以用户管理为例,除jsp页面外,四个包action、dao、service、vo。
调用关系:action——>service——>dao
![](https://box.kancloud.cn/2016-04-27_57206b05c4636.jpg)
首先,无论是哪种方法,vo包中的User类都是一样的。
~~~
public class User {
//用户id
private Integer uid;
//用户名
private String username;
//密码
private String password;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
~~~
在Action中,如果不使用模型驱动,我们需要一一构造User对象的属性,作为参数传入调用。
使用模型驱动,就要实现ModelDriven这个接口,内部方法也很简单。
~~~
public abstract interface com.opensymphony.xwork2.ModelDriven {
public abstract java.lang.Object getModel();
}
~~~
~~~
public class UserAction {
private int uid;
private String username;
private String password;
public String login(){
//构造user对象
User user = new User();
user.setUId(id);
user.setUsername(username);
user.setPassword(password);
User exitUser=userService.login(user);
if(exitUser==null){
this.addActionError("登录失败");
return "login";
}else{
//用户信息存入session、
ServletActionContext.getRequest().getSession().setAttribute("exitUser",exitUser);
return "loginSuccess";
}
}
public int getUId() {
return uid;
}
public void setId(int uid) {
this.uid = uid;
}
//剩下的get和set方法省去
......
......
}
~~~
而如果使用模型驱动,我们只需要让Action类去实现ModelDriven接口。
~~~
public class UserAction extends ActionSupport implements ModelDriven<User> {
//模型驱动使用的对象
private User user=new User();
//MdoelDriven中的方法
public User getModel(){
return user;
}
//注入userservice
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
/**
* 登录
*/
public String login(){
User exitUser=userService.login(user);
if(exitUser==null){
this.addActionError("登录失败");
return "login";
}else{
//用户信息存入session、
ServletActionContext.getRequest().getSession().setAttribute("exitUser",exitUser);
return "loginSuccess";
}
}
}
~~~
另外,模型驱动的好处还体现在**数据回显**时的应用。
在Action中,模型驱动的实体是CategorySecond,因而在回显jsp页面数据的时候,不需要保存到ValueStack值栈中,而一级分类集合cList需要保存到值栈中,前台才可以获取到值。
~~~
public class AdminCategorySecondAction extends ActionSupport implements ModelDriven<CategorySecond>{
//
//
//其余代码省去
//编辑二级分类
public String edit(){
//查询二级分类
categorySecond=categorySecondService.findByCid(categorySecond.getCsid());
//查询一级分类
List<Category> cList=categoryService.findAll();
//保存到值栈中
ActionContext.getContext().getValueStack().set("cList", cList);
return "editSuccess";
}
}
~~~
前台的部分显示如下:
~~~
<tr>
<td width="18%" align="center" bgColor="#f5fafe" class="ta_01">
二级分类名称:
</td>
<td class="ta_01" bgColor="#ffffff" >
<input type="text" name="csname" value="<s:property value="model.csname"/>" id="userAction_save_do_logonName" class="bg"/>
</td>
<td width="18%" align="center" bgColor="#f5fafe" class="ta_01">
所属的一级分类:
</td>
<td class="ta_01" bgColor="#ffffff" >
<select name="category.cid">
<s:iterator var="c" value="cList">
<option value="<s:property value="#c.cid"/>" <s:if test="#c.cid==model.category.cid">selected</s:if>><s:property value="#c.cname"/></option>
</s:iterator>
</select>
</td>
</tr>
~~~
二级分类信息使用model来显示数据,而一级分类信息接收action中传来的cList。两种方法都可以实现数据显示,但模型驱动更为简单方便。
小结:
Struts2提供的两种方式:属性驱动和模型驱动。模型驱动可以提高代码的重用性,使得操作简便。但在小型项目中,表单比较少时,并不提倡使用模型驱动。还有一点,在上面的例子中也能看出,模型驱动只能对应一个对象,当表单数据来源比较复杂时,使用模型驱动也无法起到十分明显的作用。