SSH框架中不为人知的细节(一)
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
一、 ModelDriven的運(yùn)行機(jī)制
????大家都知道前臺(tái)表單數(shù)據(jù)向后臺(tái)傳遞的時(shí)候,調(diào)用的Action會(huì)實(shí)現(xiàn)ModelDriven接口。偽碼如下:
VO偽碼:
public?class?User?{private?String?userName;private?String?password;//setter?and?getter//.... }Action偽碼:
JSP偽碼:
<form?action="xxx/user-add.action"?method="post">username:<input?type="text"?name="username"?/>password:<input?type="text"?name="password"?/><input?type="submit"?name="submit"?value="添加"?/> </form>????上面的代碼相信大家非常熟悉,但是大家知道Strusts是如何把表單的值填到VO中的?如果你確實(shí)無(wú)法回答,那么建議認(rèn)真往下讀。
????用過Struts的人一定都聽說(shuō)過值棧(后面還會(huì)專門介紹),ModelDriven背后的機(jī)制正是VlaueStack。JSP頁(yè)面上的username/password能夠被直接賦給user對(duì)象,這證明user對(duì)象是ValueStack中的一個(gè)root對(duì)象。那么,user對(duì)象是怎么進(jìn)入ValueStack的呢?答案就是ModelDrivenInterceptor,攔截器大家一定也聽說(shuō)過,在這個(gè)攔截器中,會(huì)判斷當(dāng)前要調(diào)用的Action對(duì)象是否實(shí)現(xiàn)了ModelDriven接口,如果是,這調(diào)用getModel方法,并把返回值壓入ValueStack。
ModelDrivenInterceptor的代碼:
public?class?ModelDrivenInterceptor?extends?AbstractInterceptor?{protected?boolean?refreshModelBeforeResult?=?false;public?void?setRefreshModelBeforeResult(boolean?val)?{this.refreshModelBeforeResult?=?val;}@Overridepublic?String?intercept(ActionInvocation?invocation)?throws?Exception?{Object?action?=?invocation.getAction();if?(action?instanceof?ModelDriven)?{??//判斷是否實(shí)現(xiàn)ModelDriver接口ModelDriven?modelDriven?=?(ModelDriven)?action;ValueStack?stack?=?invocation.getStack();Object?model?=?modelDriven.getModel();if?(model?!=??null)?{stack.push(model);?//將Action中g(shù)etModel()方法返回的對(duì)象壓入值棧}//下面這句條件判斷有什么作用呢,請(qǐng)繼續(xù)往下看if?(refreshModelBeforeResult)?{invocation.addPreResultListener(new?RefreshModelBeforeResult(modelDriven,?model));}}return?invocation.invoke();}????我們通過一個(gè)例子來(lái)看下為什么要refreshModelBeforeResult。
Action偽碼:
public?class?UserAction?implements?ModelDriven?{private?User?user?=?new?User();public?String?viewUser()?{//相應(yīng)的業(yè)務(wù)邏輯user?=?userService.viewUser();?//從數(shù)據(jù)庫(kù)取出數(shù)據(jù)封裝到user對(duì)象中return?"更新頁(yè)面";????}@Overridepublic?Object?getModel()?{return?user;} }JSP偽碼:
<form?action="xxx/user-update.action"?method="post">username:<input?type="text"?name="username"?value="<s:property?value="username"?/>"?/>password:<input?type="text"?name="password"?value="<s:property?value="username"?/>"?/><input?type="submit"?name="submit"?value="更新"?/> </form>????在更新操作錢,肯定需要先獲取到數(shù)據(jù),如果沒有if(refreshModelBeforeResult),user對(duì)象通過getModel()方法被壓入到ValueStack中,這時(shí)候,UserAction和ValueStack都指向同一個(gè)user對(duì)象,但緊接著,UserAction中的user被一個(gè)新的user對(duì)象覆蓋,這時(shí)候,UserAction和ValueStack不再指向同一個(gè)user對(duì)象!ValueStack中仍是舊的user對(duì)象,而UserAction中是最新的user對(duì)象,但是我們知道,在jsp頁(yè)面訪問的都是ValueStack中的user對(duì)象,所以它的屬性都將是空的。
????通過以上的分析,可以猜測(cè),通過if(refreshModelBeforeResult)最終要將最新的值壓入ValueStack。
相關(guān)源碼:
//?Add?the?new?model?on?the?stack if?(needsRefresh)?{//?Clear?off?the?old?model?instanceif?(originalModel?!=?null)?{root.remove(originalModel);}if?(newModel?!=?null)?{stack.push(newModel);} }????即將酒的model從ValueStack中移除,將新的model壓入ValueStack!
轉(zhuǎn)載于:https://my.oschina.net/vbird/blog/202500
總結(jié)
以上是生活随笔為你收集整理的SSH框架中不为人知的细节(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python数据结构——栈、队列的实现(
- 下一篇: 项目信息追踪(Log)