1. 問(wèn)題
Struts2 的 Action 我們將它定義為一個(gè)控制器,但是由于在 Action 中也可以來(lái)編寫(xiě)一些業(yè)務(wù)邏輯,也有人會(huì)在 Action 輸入業(yè)務(wù)邏輯層。
但是在企業(yè)開(kāi)發(fā)中,我們一般會(huì)將業(yè)務(wù)邏輯層單獨(dú)編寫(xiě),而不是將它與 action 層寫(xiě)到一起。
之前的練習(xí)中,我們一直將屬性如 username 、 password 等保存在了 action 中。
這樣做了以后導(dǎo)致我們?cè)谡{(diào)用業(yè)務(wù)邏輯層時(shí)可能需要將Action的對(duì)象傳過(guò)去。
但是這樣做無(wú)異于直接將 Servlet 傳給 Service,導(dǎo)致兩層之間的耦合,而且我們也不希望其他對(duì)象可以直接使用Action對(duì)象。
要解決這個(gè)問(wèn)題,我們可以采用的一種方式是,專門在Action中定義一個(gè)屬性,用來(lái)封裝信息。然后只需要將這個(gè)對(duì)象傳個(gè)service即可。
但是這樣又帶來(lái)了一個(gè)新問(wèn)題,誰(shuí)來(lái)將屬性封裝進(jìn)對(duì)象呢?答案就是ModelDriven攔截器
攔截器:
攔截器的作用和過(guò)濾器類似。
攔截器可以在請(qǐng)求到達(dá)Action之前進(jìn)行攔截,希望在請(qǐng)求到達(dá)Action之前通過(guò)攔截器做一些準(zhǔn)備工作。
Struts2 簡(jiǎn)單的運(yùn)行流程:
根據(jù)配置信息創(chuàng)建ActionProxy代理類。
判斷:如果ActionMapping為null,不是Struts請(qǐng)求,直接放行
如果ActionMapping不為null,是Struts請(qǐng)求,繼續(xù)處理
請(qǐng)求首先到達(dá)StrutsPrepareAndExecuteFilter.doFilter()
在doFilter方法中,先獲取ActionMapping
通過(guò)configurationManager加載Struts的配置信息,找到請(qǐng)求對(duì)應(yīng)的Action對(duì)象
在StrutsActionProxy.execute()方法中調(diào)用DefaultActionInvocation.invoke()方法
對(duì)所有的攔截器進(jìn)行迭代在去分別調(diào)用攔截器intercept方法,進(jìn)行攔截請(qǐng)求
intercept方法我們對(duì)請(qǐng)求進(jìn)行一些處理,處理完畢以后繼續(xù)DefaultActionInvocation.invoke()方法
如此反復(fù)直到所有的攔截器都被調(diào)用
最后才去執(zhí)行Action的方法。
2. 請(qǐng)求參數(shù)在哪封裝的:
請(qǐng)求參數(shù)在到達(dá)Action之前,會(huì)先經(jīng)過(guò)ParametersInterceptor攔截器,
在該攔截器中會(huì)自動(dòng)對(duì)將請(qǐng)求參數(shù)封裝進(jìn)值棧的棧頂對(duì)象,