ModelDriven:模型驱动,对所有action的模型对象进行批处理.

我们在开发中, 在action中一般是用实体对象,然后给实体对象get,set方法。

RegAction{
  User user ;
  //get/set
}

然后在jsp页面中给action中的user属性绑定值是通过如下方式

<s:textfield name="user.name" />
<s:textfield name="user.age" />
<s:textfield name="user.birthday" />

这样都要加上user.因为在值栈中action进入值栈的时候,值栈中存储的值就是以user.name这种形式存在的,所以ognl搜索值栈的时候,也要按这个名字来搜索。

这样就 比较麻烦,于是就引入了模型驱动。

引入模型驱动后在jsp页面绑定属性值的时候就可以不用加上user.  如:

<s:textfield name="name" />
<s:textfield name="age" />
<s:textfield name="birthday" />

原理是什么:ognl在搜索name值的时候,会把模型驱动user压入栈顶。ognl在值栈扫描的时候,会从上往下找,这样就会搜到user中的name,等等

是模型拦截器把模型压入栈顶的。

<html><head><title>reg.jsp</title></head><body><s:actionerror/><s:form namespace="/md" action="MdAction_reg" method="post" theme="xhtml" validate="true"><s:textfield name="name" label="UserName" /><s:textfield name="age" label="UserAge" /><s:submit /></s:form></body>
</html>

user类

public class User {private Integer id ;private String name ;private Integer age ;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String toString() {return "User("+id+","+name + ","+ age + ")";}
}

/*** MdAction:某型驱动*/
public class MdAction extends ActionSupport implements ModelDriven<User>,Preparable {private String name;  由于使用了模型驱动,user处于栈顶,user中也有name,那么jsp页面绑定的name是user中name,并不是这里的name,所以该name值为null,同理在修改功能传id的时候,如果user中有id属性,而在action中也定义了一个id来接收该参数,这样id也接收不到值,因为使用了模型驱动后,模型驱动拦截器会把id的值传给user中的id,而不是action中的id属性,为了解决这个问题,需要把action中接收参数id的属性定义为别的名称。比如uid,同时修改jsp中的传参为uid,这样就解决了这个问题。这是在使用模型驱动的时候需要注意的地方。

    private User user = new User();属性user,模型驱动栈顶的对象

    public String reg() {return "success";}@SkipValidationpublic String toRegView() {System.out.println("toRegView");return "regView";}    public User getModel() {return user;}public String getName() {return name;}public void setName(String name) {this.name = name;}

public User getModel() {
          return user;//这里返回的就是action中的属性user,如果在action中的其他方法里,使用了User user=new User(),那么这个user对象就不是模型驱动的的对象,

也就是不处在栈顶。即使把当前new出的user赋值给属性user也不行,因为在值栈中是通过引用来实现,即值栈中是对象的地址。
      }

public String Edit()

    {

    User u = new User();

    u.setId(uid);

    u.setName("jerry");
    u.setAge(30);
    user = u ;注意,这里的user并不是栈顶的user,引用已经指向了新对象u

    如果要把u对象放到栈顶,可以手动的push

    ServletActionContext.getContext().getValueStack().push(u) ;//把u对象放到栈顶,那么执行修改时回显的就是该对象的数据。

   }

}

上面的方法是手动把u对象压入栈顶,还有一种方法可以解决这个问题。

模型驱动拦截器的高级应用:

struts在调用模型驱动拦截器的之前会调用prepare拦截器,prepare拦截器中会调用一个prepare方法,该方法在模型驱动拦截器之前调用,也就是在模型驱动

拦截器中的getModel方法之前执行,getModel方法返回的就是栈顶的对象,那么可以在prepare中把getModel方法中要返回到栈顶的对象给换掉,也就是重新引用。

这样就不用手动的push到栈顶了。

/*** MdAction:某型驱动*/
public class MdAction extends ActionSupport implements ModelDriven<User>,Preparable {private static final long serialVersionUID = -6933309304624396640L;private String name;private Integer uid ;private User user = new User();//模型驱动的getModel方法返回到栈顶的对象。userprivate List<User> userList ;public String reg() {return "success";}@SkipValidationpublic String toRegView() {System.out.println("toRegView");return "regView";}/*** 查询所有用户*/public String findAllUsers(){userList = new ArrayList<User>();User u = null ;for(int i= 0 ; i < 10 ; i ++){u = new User();u.setId(1 + i);u.setName("tom" + i);u.setAge(20 + i);userList.add(u);}return "userListView";}public String edit(){return "editView" ;}//
    public User getModel() {return user;}public String getName() {return name;}public void setName(String name) {this.name = name;}public List<User> getUserList() {return userList;}public void setUserList(List<User> userList) {this.userList = userList;}public Integer getUid() {return uid;}public void setUid(Integer uid) {this.uid = uid;}/*** 该方法在getModel之前运行,在modelDriven拦截器之前先运行*/public void prepareEdit() throws Exception { 该命名规则说明在执行Edit的时候才会执行该方法。//
        User u = new User();u.setId(uid);u.setName("jerry");u.setAge(30);    user = u ;把user对象换掉,换成新new出的对象。}public void prepare() throws Exception {}
}

但是由于使用的是默认拦截器栈,prepare拦截器在params拦截器之前执行,这样在编辑的时候,就无法获取到id值,因为此时还没有经过参数params烂机器的处理。

所以这种方法不能使用默认的拦截器栈,struts-default.xml提供了一个拦截器栈paramsPrepareParamsStack,所以要引入该拦截器栈。

<struts><package name="MdPkg" namespace="/md" extends="struts-default"><action name="MdAction_*" class="struts2.modeldriven.MdAction" method="{1}"><result name="success">/md/reg.jsp</result><result name="regView">/md/reg.jsp</result><result name="editView">/md/edit.jsp</result><result name="userListView">/md/userList.jsp</result><interceptor-ref name="paramsPrepareParamsStack" /> 不能引入默认拦截器栈,要在prepare拦截器之前执行params拦截器</action></package>
</struts>

模型驱动的应用:

假设在开发中有很多实体对象,比如用户类User,订单类Order,部门类Department等等

对应的有很多Action,如UserAction,OrderAction,DepartmentAction等等。

UserAction{

  User user;

}

OrderAction{

  Order order;

}

如果在开发中需要开发一个处理模型的拦截器

ProcessModelInterceptor{

  if(action instanceof(UserAction){

    Object o=getUser();//得到该实体类的对象

  }

else if(action instanceof(OrderAction){

    Order o=getOrder();//得到该实体类的对象

  }

....

这样如果有很多的类几十甚至上百个实体类,都要这么去判断,将是十分的麻烦。引入了模型驱动后就解决了这个问题。

}

引入模型驱动后的做法:模型驱动的好处是对所以的action模型对象进行批处理

ProcessModelInterceptor{

  if(action instanceof(ModelDriven){//判断action是否实现了模型驱动接口

    Object o=((ModelDriven)action).getModel();//得到action的模型对象

    然后用反射获取action中的信息

  }

}

转载于:https://www.cnblogs.com/lxboy2009/p/6105605.html

模型驱动 ModelDriven相关推荐

  1. 从Java类库看设计模式

    //From http://www.uml.org.cn/j2ee/201010214.asp 很多时候,对于一个设计来说(软件上的,建筑上的,或者它他工业上的),经验是至关重要的.好的经验给我们以指 ...

  2. Struts2 入门

    一.Struts2入门案例 ①引入jar包 ②在src下创建struts.xml配置文件 <?xml version="1.0" encoding="UTF-8&q ...

  3. java登录中用户类型分类_基于用户登陆的struts2中action的分类详解

    在struts2中action的分类有:继承 ActionSupport 实现 Action,模型驱动(ModelDriven)的 Action,多方法的 Action三种方式. 1.继承 Actio ...

  4. Struts2数据封装

    Struts2数据封装 Struts2提供了一些基于拦截器的数据封装方式,一共有四种,分为静态参数封装和动态属性封装,动态属性封装又可分为属性驱动和模型驱动,属性驱动又可分为基本属性驱动和对象图导航语 ...

  5. stucts2 页面上的值如何与Action的属性值对应

    在Strut2中,页面的数据和Action有两种基本对应方式:分别是:属性驱动(FieldDriven)和模型驱动(ModelDriven).属性驱动又分为两种情况:一种是基本数据类型的属性对应:另一 ...

  6. (转)Struts2访问Servlet的API及......

    http://blog.csdn.net/yerenyuan_pku/article/details/67315598 Struts2访问Servlet的API 前面已经对Struts2的流程已经执行 ...

  7. 2016最新Java学习计划

    一.Java学习路线图 二.Java学习路线图--视频篇 六大阶段 学完后目标 知识点 配套免费资源(视频+笔 记+源码+模板) 密码        第一阶段 Java基础 入门 学习周期: 35天 ...

  8. JavaEE全套资料+视频+工具

    JavaEE全套资料+视频+工具[点击链接原文] Java学习路线图引言: 一.Java学习路线图-流程篇: 二.Java学习路线图-视频篇: 1.第一阶段-Java基础入门 Java视频篇第一阶段- ...

  9. 【SSH框架/国际物流商综平台】-03 部门、用户、角色、模块 CURD BRAC认证 细粒度权限控制 BaseAction Page struts.xml *.hbm.xml

    一.回顾 1.项目首页面执行过程分析 2.顶部菜单点击后,为什么左侧,中间区域会改变 3.为什么左侧菜单点击后,显示结果在中间区域 4.DAO分析 5.Page分页组件 6.编写及酉己置Service ...

最新文章

  1. java指令集_javap 指令集
  2. 《Raspberry Pi用户指南》——导读
  3. python数据分析方向_python数据分析方向,面试题解答
  4. NLTK基础 | 一文轻松使用NLTK进行NLP任务(附视频)
  5. 提升业务价值 APM应用与整合分享
  6. 用properties写的一个程序运行次数计数的程序代码,超过次数提示注册。
  7. 判断app访问还是web访问网站
  8. 2.14.PHP7.1 狐教程-【PHP 静态类、静态方法、静态属性】
  9. jsp中的九大内置对象和四大作用域
  10. QQ头像无法加载,显示初始默认头像的解决方法
  11. python 在线客服_如何利用Python实现简单全双工在线客服系统!这个有点东西!...
  12. 排兵布阵问题java语言_hdu 4539 郑厂长系列故事——排兵布阵
  13. 命名转小驼峰大驼峰中划线
  14. 漫画|电话会议炸出了同事里的隐形富豪
  15. oracle之SQL的基本函数
  16. 服务器心跳信号,服务器心跳攻击
  17. 2021年起重机司机(限桥式起重机)考试技巧及起重机司机(限桥式起重机)考试平台
  18. mysql 多表 left join_MySql left join 多表连接查询优化语句
  19. Windows应用商店保留Windows 7特色
  20. 徐梓喆 11月20日 C语言 猴子吃peach

热门文章

  1. 编写高质量代码-OC 第7章 设计模式与Cocoa编程
  2. 设计模式之单件模式(Singleton Pattern)
  3. MSN和QQ文件传输速度解析
  4. 高斯曲率求表面极值点
  5. webservice生成客户端的方法
  6. mac php gd库,mac下安装GD库FreeType
  7. html网页制作图案,巧用CSS滤镜做图案文字-网页设计,HTML/CSS
  8. uniapp框架之如何修改接口传参的参数
  9. 正则表达式常用符号所代表的含义
  10. 【APICloud系列|12】ios真机调试时如何添加新设备的udid?