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