Struts2 總結
1.控制器采用的是 Filter 這個服務器端組件,相比於 Servlet ,Servlet 能獲取到的資源,Filter 也同樣能獲取到,不同的是 Filter 生命周期初始化和 Servlet 有所區別。
2.Struts2 使用 Filter 和 Interceptors 完成了表述層要解決的常見問題,如異常處理,防止表單重復提交,文件上傳下載,類型轉換,國際化等。
而自定義的攔截器又為其他問題進行了擴展。
3.Struts2 使用 ValueStack 和 ModelDriven 使開發更加便捷。
ValueStack 可以看成是 Struts2 的一個容器,也可以看成是 表述層的一個容器。
結合 OGNL 表達式和 Struts2 標簽,可以在頁面中獲取到任何想獲取到的資源,比如域對象中的信息,請求參數,Web資源等,錯誤信息等。
而 ModelDriven 為請求參數提供了一種基於對象的注入,使開發更加便捷。
4.每一個 Struts2 請求會對應一個 ValueStack(它存在於整個 Action 生命周期內,在 Struts2 請求接受到請求的時候創建,隨請求的結束而結束),對應一個
Action 對象,對應一個 action(實際處理請求的方法) 請求,保證了線程之間的安全性,但是也極大的消耗了服務器資源。
5.Struts2 是這樣運行的:
(1)在 Web 應用啟動時,執行了 Struts2 的核心 Filter(StrutsPrepareAndExecuteFilter) 的初始化方法,接受到一個請求時,執行 doFilter() 方法,在 doFilter()
方法中,先對請求和響應對象進行了強轉,轉為對應的 HttpServletXxx 對象,然後判斷這個請求如果不是一個 Struts2 請求,則直接放行。如果是一個 Struts2 請求,
則根據請求內容的類型不同而包裝為不同的 請求包裝類對象。如果為 multipart/form-data 類型,則返回對應的包裝類型 MultiPartRequestWrapper,其他情況下
返回 StrutsRequestWrapper 對象,request 對象重新包裝過後,通過 ActionMapper 的 getMapping() 方法得到ActionMapping,如果 mapping 為空,判斷
請求的是否為靜態資源,若為靜態資源,則直接放行。若 mapping 不為空,則執行 Action,Action的配置信息存儲在 ActionMapping 對象中。
將調用 Dispatcher.serviceAction()方法。如圖:
(2)在 Dispatcher.serviceAction()方法中,做了兩件事。
一是根據給定的參數,創建了 ActionContext,以及 ValueStack 的獲取(如果已經存在一個ValueStack,則復制一份到新的 Action 請求中)。
二是:在配置信息加載完成後,創建 ActionProxy 對象(Action 的代理對象)。
ActionProxy 是由 ActionProxyFactory 創建,ActionProxyFactory是創建 ActionProxy 的工廠。
其中ActionProxy 和 ActionProxyFactory 都是借口,默認實現為:DefaultActionProxy 和 DefaultActionProxyFactory,在 xwork2 包下。
在 DefaultActionProxy 中,實際向後調用的是 ActionInvocation 的 invoke() 方法。
DefaultActionInvocation 作為 ActionInvocation 的默認實現。在 DefaultActionInvocation的 invoke() 方法中,實現了攔截器的遞歸調用和
執行目標 Action 的 execute() 方法。其中遞歸調用攔截器的代碼如下:
if (interceptors.hasNext()) { final InterceptorMapping interceptor = interceptors.next(); String interceptorMsg = "interceptor: " + interceptor.getName(); UtilTimerStack.push(interceptorMsg); try { resultCode = interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally { UtilTimerStack.pop(interceptorMsg); } }
如果攔截器全部執行完畢,則調用 invokeActionOnly() 方法執行目標 Action。最後調用的是 DefaultActionInvocation.invokeAction() 方法。調用關系如下:
ActionProxy:管理了 Action 的生命周期。
ActionInvocation:在 ActionProxy 層下,是真正干活的。
最後通過 Result 進行頁面的跳轉。
6.Struts 中需要添加配置文件的幾個地方。
(1)struts.xml 文件,如果需要按照模塊劃分的話,還需要增加對應的配置文件。
(2)修改主題模板
(3)自定義類型轉換器。Action 級別和 全局級別是配置方式是不一樣的。
(4)輸入驗證。同樣的有兩種方式,一種是對當前 Action 類的所有 action 使用同樣的驗證規則,二種是對當前 Action 類的具體某個 action 使用驗證規則。
(5)國際化資源文件
(5)自定義攔截器
7.在我看來的 Struts2 優缺點:
優點:
Struts2 為常見的 Web 方面的問題提供了解決方案,攔截器和值棧作為核心,在頁面中又有 Struts2 自己的標簽,思想比較簡單,也便於開發。
在看Struts2 源碼的時候,發現它的命名特別易懂。同時 Struts2 源碼也比較易讀。
缺點:
配置繁瑣,往往是每個 Action 對應一個配置文件。
只能進行屬性的驗證,不能對 model 進行驗證。
雖然對當前 表述層存在的問題都進行了解決,但是開發起來還是比較繁瑣。
simple 主題也含有默認樣式。