在web.xml文件里配置一個(gè)派遣器ServletDispatcher,以接收所有以action結(jié)尾的url請(qǐng)求。并進(jìn)行http請(qǐng)求調(diào)度處理.
<servlet>
<servlet-name></servlet-name>
<servlet-class>com.opensymphony.webwork.dispatcher.ServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>webwork</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
當(dāng)ServletDispatche調(diào)度器接收到一個(gè).action結(jié)尾的請(qǐng)求時(shí),會(huì)調(diào)用ServletDispatche類(lèi)的service方法進(jìn)行處理,該方法最終是創(chuàng)建一個(gè)ActionProxy對(duì)象,并通過(guò)執(zhí)行ActionProxy中的execute方法來(lái)
調(diào)用所請(qǐng)求的Action的execute方法.之前要執(zhí)行一些方法來(lái)創(chuàng)造條件:創(chuàng)建Action上下文===>從request中獲得值堆棧stack===>創(chuàng)建ActionProxyFactory對(duì)象,并初始化一個(gè)DefaultActionProxy對(duì)象====>通過(guò)DefaultAction的構(gòu)造函數(shù)調(diào)用ConfigurationManager獲得當(dāng)前請(qǐng)求的Action在xwork.xml中的配置信息====>DefaultActionProxy中的prepare方法通過(guò)創(chuàng)建一個(gè)ActionInvocation對(duì)象來(lái)實(shí)現(xiàn)對(duì)請(qǐng)求action的調(diào)用。
AroundInterceptor攔截機(jī)-->
DefaultActionInvocation中有一個(gè)數(shù)組維護(hù)了攔截機(jī)的執(zhí)行順序:
1、StaticParametersInterceptor, 2、ParametersInterceptor, 3、WebWorkConversionErrorInterceptor
4、ModelDrivenInterceptor 5、ExternalReferencesInterceptor
6、StaticParametersInterceptor 7、parametersInterceptor, 8、WebWorkConversionErrorInterceptor
9、ModelDrivenInterceptor 10、ValidationInterceptor
注:這里1、2、3、4攔截機(jī)執(zhí)行了兩次,為什么會(huì)執(zhí)行兩次呢?
疑問(wèn):這里的執(zhí)行順序和webwork-default.xml中的<interceptors>配置有何關(guān)聯(lián)?
Action ---> 根據(jù)Action實(shí)現(xiàn)相應(yīng)的Action,ModelDriven接口調(diào)用基類(lèi)的
ParametersInterceptor中:
final Map parameters = ActionContext.getContext().getParameters();
從AroundInterceptor的context中取出頁(yè)面提交字段的名稱(chēng)和值,然后它會(huì)先把stack.pus(modelDriven.getModel()); modelDriven.getModel()放到CompoundRoot中(CompounRoot是一個(gè)ArrayList)上面提到有四個(gè)攔截機(jī)執(zhí)行兩次,因?yàn)榈谝淮我猵ush進(jìn)去一個(gè)空的對(duì)象,方便填值,第二次放的是填充好的對(duì)象。也就是Action中g(shù)etModel()的對(duì)象。把值從parameters 設(shè)置到OgnlValueStack的CompoundRoot的第一個(gè)下標(biāo)中的Action里的getModel()對(duì)象里code:stack.setValue(name, value);name對(duì)應(yīng)的是getModel()對(duì)應(yīng)的字段,value為要填充的值.
摘要: 最近偶參與一個(gè)J2EE項(xiàng)目,應(yīng)用架框是struts+spring! 持久層用hibernate,由于業(yè)務(wù)需要,業(yè)務(wù)數(shù)據(jù)來(lái)源來(lái)二個(gè)不同的數(shù)據(jù)庫(kù)數(shù)據(jù)庫(kù)是Orcale,版本是9.0.1.0.0。由于采用容器管理事務(wù)(CMT),對(duì)于Spring,一般普通業(yè)務(wù)應(yīng)用我用聲明式事務(wù),因?yàn)檫@樣讓代碼清潔一點(diǎn),只有對(duì)于特殊的業(yè)務(wù)我才用編程式事務(wù),如大批量更新時(shí)調(diào)用存儲(chǔ)過(guò)程。對(duì)于WebLog... 閱讀全文 POJO(plain old java Object)[譯:簡(jiǎn)單初始Java對(duì)象]。它簡(jiǎn)單(因?yàn)橹挥衧et/get方法)嗎?或是我們把應(yīng)該把它弄得復(fù)雜點(diǎn)(帶點(diǎn)業(yè)務(wù)判斷)?究竟它在我們J2EE應(yīng)用中扮演一個(gè)什么樣的角色呢?一個(gè)Anemic Domain Model,Rich Domain Model, DTO, O/R mapping Entity........!以前我的系統(tǒng)中POJO都是一個(gè)貧血的模型,只有set/get方法!它的職責(zé)就是把前端頁(yè)面的數(shù)據(jù)從formBean中轉(zhuǎn)移過(guò)來(lái)(用反射),作為持久層的對(duì)象。這里POJO有兩個(gè)角色,一個(gè)角色是傳送數(shù)據(jù),另一個(gè)是角色是PO(持久對(duì)象)。一段時(shí)間后我發(fā)現(xiàn)這樣做效率低下,想像一下有些業(yè)務(wù)處理,如一個(gè)銀行帳戶(hù)的pojo,里面有一個(gè)金額和利息字段,這個(gè)金額是通過(guò)一些公式計(jì)算后得出來(lái)的,開(kāi)始時(shí)我們?cè)跇I(yè)務(wù)層里把金額算出來(lái)后set到帳戶(hù)pojo金額字段里。我開(kāi)始思索把一些都是計(jì)算或者純邏輯的東西pull Up到pojo中。這時(shí)候我的pojo變成一個(gè)Domain Object。盡管不是一個(gè)Rich的Domain Model,但畢竟前進(jìn)了一小步。再后來(lái)用到了webwork2,由于webwork2里沒(méi)有了struts formBean,使用攔截機(jī)設(shè)值,ModelDriven模式下我的持久Entity就是一個(gè)formBean和po的結(jié)合, 在A(yíng)CTIO中它是一個(gè)有值的VO,在DAO實(shí)現(xiàn)層變成一個(gè)PO。在這里我的pojo繼承了O/R Entity類(lèi),并把合適的業(yè)務(wù)層的代碼都移到相應(yīng)的了Pojo中,當(dāng)然沒(méi)有持久層的代碼。這樣我的系統(tǒng)的部分pojo變成了Rich Domain Model。在Ejb下,由會(huì)話(huà)門(mén)面管理對(duì)POJO業(yè)務(wù)對(duì)象訪(fǎng)問(wèn)對(duì)比起笨重的entity bean有更高的效率和可移植性。盡管Ejb下的POJO不能享受entity bean的CMP策略,但有了spring 的IOC后,一切變得可配置了!POJO還有很重要的一個(gè)優(yōu)勢(shì)就是pojo中的業(yè)務(wù)可以脫離具體容器運(yùn)行測(cè)試!在這里,pojo是貧血還是沖血應(yīng)該取決于你的業(yè)務(wù)應(yīng)用,記住:不要把簡(jiǎn)單的問(wèn)題搞復(fù)雜了,但把復(fù)雜的問(wèn)題分解成簡(jiǎn)單的問(wèn)題一直就是我們追求的!