模型驱动 ModelDriven

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373389.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本月风味– Neo4j和Heroku

Neo4j今年早些时候发起了一项挑战&#xff0c;即“ 种子播云 ”&#xff0c;以使人们使用Neo4j附加组件在Heroku上创建模板或演示应用程序。 经过许多内部辩论之后&#xff0c;我决定进入&#xff0c;但由于缺乏想法而陷入绝望。 当我什么都没做的时候&#xff0c;这个主意就出…

1 + 11 + 1111+ 11111+ ..... + 11111(2016个) 结果是几位数

# -*- coding: utf-8 -*- """ Created on Mon Mar 21 20:38:06 2016author: yanjie """1 11 1111 11111 ..... 11111(2016个) 结果是几位数 用什么数据结构 有几个6 写算法a []; m 0; six 0; for i in range(2016,0,-1):b (im) % 10;m (…

[回归分析][10]--相关误差的问题

[回归分析][10]--相关误差的问题这一篇文章还是来分析相关误差的问题。 1.游程数 定义&#xff1a;游程数--残差穿过x-轴的次数 用这个可以检查如残差有一块在x轴上面&#xff0c;一块在x轴下面的情形。 如上面这样的残差 下面构造两个统计量&#xff1a; 其中 n…

Spring 3 MVC异常处理程序

我遇到的大多数Spring 3错误处理示例代码似乎都提供了其用法的最简单概述&#xff0c;但是&#xff0c;有人说&#xff0c;如何处理错误比正常代码的工作方式更为重要。 前一天&#xff0c;当我在Spring&#xff08;2&#xff09;错误处理程序中遇到一个简单的GOTCHA时&#xf…

java编译找不到符号_javac编译时找不到符号?

我是个新手&#xff0c;在linux使用java编程时&#xff0c;出现这个情况。我把要引的包放在classpath中&#xff0c;红色部分&#xff1a;export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$HADOOP_HOME/hadoop-1.0.4.core.jar:${CLASSPATH}通过echo $CLASSP…

全备份、差异备份和增量备份概念详述

全备份、差异备份和增量备份概念详述 1、完全备份&#xff08;Full Backup&#xff09; 备份全部选中的文件夹&#xff0c;并不依赖文件的存档属性来确定备份那些文件。在备份过程中&#xff0c;任何现有的标记都被清除&#xff0c;每个文件都被标记为已备份。换言之&#xff0…

微信接入登录功能access_token流程记录

提示&#xff1a;只有认证过的订阅号或者服务号才能获取access_token。 1.app微信登录第一步是&#xff0c;app调起来微信客户端&#xff0c;通过app端的配置&#xff0c;引入一个微信类库&#xff0c; 2.授权成功后&#xff0c;微信会返回你一个code。 将APP_ID替换成你在微信…

使用MVC模式制作游戏-教程和简介

游戏开发中一种有用的体系结构模式是MVC&#xff08;模型视图控制器&#xff09;模式。 它有助于分离输入逻辑&#xff0c;游戏逻辑和UI&#xff08;渲染&#xff09;。 在任何游戏开发项目的早期阶段&#xff0c;其实用性很快就会被注意到&#xff0c;因为它允许快速更改内容&…

boost

参考博客 http://www.cnblogs.com/lidabo/p/3805487.html http://www.cppblog.com/Robertxiao/archive/2013/01/06/197022.html http://www.cnblogs.com/finallyliuyu/archive/2013/05/23/3094246.html http://www.cnblogs.com/lidabo/p/3782193.html http://www.cnblogs.com/z…

moment格式换时间_不一样的日期、时间转换(moment.js)

无意中遇到了一种很奇怪的日期格式&#xff0c;从接口中返回的日期是这样的&#xff0c;如 2018-02-06T11:59:2208:00 。然而这却不是我们想要的&#xff0c;我们要的是这种&#xff0c;YYYY-MM-DD HH:mm:ss。那么这种是怎么转换的呢&#xff1f;这时候就可以使用一款很好用的日…

并发模式:生产者和消费者

在我15年的职业生涯中&#xff0c;生产者和消费者的问题是我仅遇到过几次。 在大多数编程情况下&#xff0c;我们正在做的事情是以同步方式执行功能&#xff0c;其中JVM或Web容器自行处理多线程的复杂性。 但是&#xff0c;在编写某些需要的用例时。 上周&#xff0c;我遇到了一…

POJ 1006 - Biorhythms (中国剩余定理)

B - BiorhythmsTime Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1006Description 人生来就有三个生理周期&#xff0c;分别为体力、感情和智力周期&#xff0c;它们的周期长度为23天、28天和33天。每一个周期中…

子线程中更新UI线程的三个方法

1、通过handler方式&#xff0c;sendmessage。 多个类间传递比较麻烦&#xff0c;也懒的写... 2、线程中通过runOnUiThread&#xff08;&#xff09; new Thread() { public void run() { //这儿是耗时操作&#xff0c;完成之后更新UI&#xff1b; runOnUiThread(new Runnab…

mysql limit acs_mysql查询操作

简单查询&#xff1a;select * from 表名;避免重复&#xff1a;select distinct 字段 from 表名;条件查询&#xff1a;select 字段,字段 from 表名 where id<5(条件);四则运算查询&#xff1a;select id,dep_id,id*dep_id from company.employee5 where id<5;定义显示格式…

作业管理系统数据字典

转载于:https://www.cnblogs.com/heyangcan/p/5312394.html

使用Hive和iReport进行大数据分析

每个JJ Abrams的电视连续剧疑犯追踪从主要人物芬奇先生一个下列叙述情节开始&#xff1a;“ 你是被监视。 政府拥有一个秘密系统-每天每天每小时都会对您进行监视的机器。 我知道是因为...我建造了它。 “当然&#xff0c;我们的技术人员知道得更多。 庞大的电气和软件工程师团…

docker集群管理

docker集群管理 ps&#xff1a;docker machine docker swarm docker compose 在Docker Machine发布之前&#xff0c;你可能会遇到以下问题&#xff1a; 你需要登录主机&#xff0c;按照主机及操作系统特有的安装以及配置步骤安装Docker&#xff0c;使其能运行Docker…

从0学java_从零开始学JAVA(一.Java的基础语法)

基本语法编写 Java 程序时&#xff0c;应注意以下几点&#xff1a;大小写敏感&#xff1a;Java 是大小写敏感的&#xff0c;这就意味着标识符 Hello 与 hello 是不同的。类名&#xff1a;对于所有的类来说&#xff0c;类名的首字母应该大写。如果类名由若干单词组成&#xff0c…

linux mount (挂载命令)详解

挂接命令(mount) 首先&#xff0c;介绍一下挂接(mount)命令的使用方法&#xff0c;mount命令参数非常多&#xff0c;这里主要讲一下今天我们要用到的。 命令格式&#xff1a;mount [-t vfstype] [-o options] device dir 其中&#xff1a; 1.-t vfstype 指定文件系统的类型&…

Android官方培训课程中文版(v0.9.5)

http://hukai.me/android-training-course-in-chinese/index.html转载于:https://www.cnblogs.com/xiaoyao095/p/6125715.html