ModelDriven:模型驅(qū)動,對所有action的模型對象進行批處理. 我們在開發(fā)中, 在action中一般是用實體對象,然后給實體對象get,,set方法,。 RegAction{ 然后在jsp頁面中給action中的user屬性綁定值是通過如下方式 <s:textfield name="user.name" /> 這樣都要加上user.因為在值棧中action進入值棧的時候,,值棧中存儲的值就是以user.name這種形式存在的,,所以ognl搜索值棧的時候,,也要按這個名字來搜索,。 這樣就 比較麻煩,,于是就引入了模型驅(qū)動,。 引入模型驅(qū)動后在jsp頁面綁定屬性值的時候就可以不用加上user. 如: <s:textfield name="name" /> 原理是什么:ognl在搜索name值的時候,會把模型驅(qū)動user壓入棧頂,。ognl在值棧掃描的時候,,會從上往下找,這樣就會搜到user中的name,,等等 是模型攔截器把模型壓入棧頂?shù)摹?/span>
<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:某型驅(qū)動 */ public class MdAction extends ActionSupport implements ModelDriven<User>,Preparable { 也就是不處在棧頂,。即使把當前new出的user賦值給屬性user也不行,因為在值棧中是通過引用來實現(xiàn),,即值棧中是對象的地址,。 public String Edit() { User u = new User(); u.setId(uid); u.setName("jerry"); 如果要把u對象放到棧頂,,可以手動的push ServletActionContext.getContext().getValueStack().push(u) ;//把u對象放到棧頂,那么執(zhí)行修改時回顯的就是該對象的數(shù)據(jù),。 } }
上面的方法是手動把u對象壓入棧頂,還有一種方法可以解決這個問題,。 模型驅(qū)動攔截器的高級應(yīng)用: struts在調(diào)用模型驅(qū)動攔截器的之前會調(diào)用prepare攔截器,,prepare攔截器中會調(diào)用一個prepare方法,該方法在模型驅(qū)動攔截器之前調(diào)用,,也就是在模型驅(qū)動 攔截器中的getModel方法之前執(zhí)行,,getModel方法返回的就是棧頂?shù)膶ο螅敲纯梢栽趐repare中把getModel方法中要返回到棧頂?shù)膶ο蠼o換掉,,也就是重新引用,。 這樣就不用手動的push到棧頂了。
/** * MdAction:某型驅(qū)動 */ 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();//模型驅(qū)動的getModel方法返回到棧頂?shù)膶ο?。user private List<User> userList ; public String reg() { return "success"; } @SkipValidation public 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 { 該命名規(guī)則說明在執(zhí)行Edit的時候才會執(zhí)行該方法,。 // User u = new User(); u.setId(uid); u.setName("jerry"); u.setAge(30); user = u ;把user對象換掉,換成新new出的對象,。 } public void prepare() throws Exception { } }
但是由于使用的是默認攔截器棧,,prepare攔截器在params攔截器之前執(zhí)行,這樣在編輯的時候,,就無法獲取到id值,,因為此時還沒有經(jīng)過參數(shù)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攔截器之前執(zhí)行params攔截器 </action> </package> </struts>
模型驅(qū)動的應(yīng)用: 假設(shè)在開發(fā)中有很多實體對象,,比如用戶類User,訂單類Order,,部門類Department等等 對應(yīng)的有很多Action,,如UserAction,OrderAction,,DepartmentAction等等,。 UserAction{ User user; } OrderAction{ Order order; } 如果在開發(fā)中需要開發(fā)一個處理模型的攔截器 ProcessModelInterceptor{ if(action instanceof(UserAction){ Object o=getUser();//得到該實體類的對象 } else if(action instanceof(OrderAction){ Order o=getOrder();//得到該實體類的對象 } .... 這樣如果有很多的類幾十甚至上百個實體類,都要這么去判斷,,將是十分的麻煩,。引入了模型驅(qū)動后就解決了這個問題。 }
引入模型驅(qū)動后的做法:模型驅(qū)動的好處是對所以的action模型對象進行批處理 ProcessModelInterceptor{ if(action instanceof(ModelDriven){//判斷action是否實現(xiàn)了模型驅(qū)動接口 Object o=((ModelDriven)action).getModel();//得到action的模型對象 然后用反射獲取action中的信息 } } |
|