模型驅動 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.pswp.cn/news/373389.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373389.shtml
英文地址,請注明出處:http://en.pswp.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