2015年3月7日11:02:55css
Strust2的MVC對應關係以下:html
在MVC三個模塊當中,struts2對應關係以下:java
Model:web
負責封裝應用的狀態,並實現應用的功能。一般分爲數據模型和業務邏輯模型,數據模型用來存放業務數據,好比訂單信息、用戶信息等;而業務邏輯模型包含應用的業務操做,好比訂單的添加或者修改等。spring
封裝應用狀態:某些應用數據封裝起來,使得視圖只能經過接口獲取對應的數據apache
響應狀態查詢:對應用的狀態改變進行處理安全
暴露應用功能:暴露接口mvc
通知視圖改變:主動向視圖傳遞數據app
Controller:框架
用來控制應用程序的流程和處理視圖所發出的請求。當控制器接收到用戶的請求後,會將用戶的數據和模型的更新相映射,也就是調用模型來實現用戶請求的功能;而後控制器會選擇用於響應的視圖,把模型更新後的數據展現給用戶。
接受並驗證HTTP請求的數據:對一個url請求,經過Controller將請求分發到指定的處理模塊上。
將用戶數據域模型的更新相映射:用戶數據模型改變並不會當即對應到Model,而是須要controller來分發
選擇用於響應的視圖:根據配置文件,選擇對應與某個模型的視圖
View:
用來將模型的內容展示給用戶,用戶能夠經過視圖來請求模型進行更新。視圖從模型得到要展現的數據,而後用本身的方式展示給用戶,至關於提供界面來與用戶進行人機交互;用戶在界面上操做或者填寫完成後,會點擊提交按鈕或是以其它觸發事件的方式,來向控制器發出請求。
解析模型的數據:如velocity的功能
產生HTML的響應:
請求模型的更新:向後臺發送表單
發送用戶輸入給控制器
一個請求在Struts2框架中的處理大概分爲如下幾個步驟:
總體流程
l 客戶端提交一個HttpServletRequest請求(action或JSP頁面)。
l 請求被提交到一系列Filter過濾器,如ActionCleanUp和FilterDispatcher等。
l FilterDispatcher是Struts2控制器的核心,它一般是過濾器鏈中的最後一個過濾器。
l 請求被髮送到FilterDispatcher後,FilterDispatcher詢問ActionMapper時候須要調用某個action來處理這個Request。
l 若是ActionMapper決定須要調用某個action,FilterDispatcher則把請求交給ActionProxy進行處理。
l ActionProxy經過Configuration Manager詢問框架的配置文件struts.xml,找到調用的action類。
l ActionProxy建立一個ActionInvocation實例,經過代理模式調用Action。
l action執行完畢後,返回一個result字符串,此時再按相反的順序經過Intercepter攔截器。
l 最後ActionInvocation實例,負責根據struts.xml中配置result元素,找到與之相對應的result,決定進一步輸出。
Struts2的action生命週期
Struts2的action接口隔離
Struts2中的Action,並不須要依賴於特定的Web容器。咱們看不到相似HttpServletRequest,HttpServletResponse等Web容器相關的對象。
提問:Struts2的Action並不帶有任何Web容器相關的對象,Action又是如何工做在Web容器中的呢?
雖然Struts2的Action只是一個很是普通的Java對象,並不具有任何Web容器的特質,可是咱們須要把Action放到一個更加大的環境中來看。事實上,Struts2爲Action的執行,準備了完整的數據環境和執行環境。而這個執行環境,就保證了Action在Web容器中的順利運行。
在Struts2中,每一個Http的請求,會被髮送到一個Filter。而這個Filter,就會針對每一個請求,建立出一個代碼的執行環境,並在這個基礎上,爲每一個執行環境配備與之對應的數據環境,這個數據環境中的內容,就來自於Web容器中的一個又一個對象。這樣,就可以順利調用Action執行代碼而無需擔憂它是否運行在Web容器中了。
提問:Struts2的Action並不帶有任何Web容器相關的對象,Action中又如何與Web容器進行通訊並獲取Web容器的相關對象呢?
剛剛咱們提到Struts2會爲每一個Http的請求創建一個執行環境和數據環境。其中,數據環境就成爲了Action獲取Web容器的基礎。因此,當Action須要獲取Web容器的相關對象,須要經過數據環境來進行。
Struts2設置的優勢
1. 使得Struts2的Action很是易於測試
若是咱們徹底不考慮Action的執行環境,僅僅把Action看做一個普通的Java對象,那麼咱們甚至能夠直接new一個Action的對象,經過執行其中的方法完成測試。這樣,咱們就不須要任何的Mock,來模擬Web容器的環境。
2. 結合Action的執行環境,使得Struts2在Control這個層次上,可以定義更加豐富的執行層次
由於Action是一個普通的Java類,而不是一個Servlet類,徹底脫離於Web容器,因此咱們就可以更加方便地對Control層進行合理的層次設計,從而抽象出許多公共的邏輯,並將這些邏輯脫離出Action對象自己。事實上,Struts2也正是這麼作的,不管是Interceptor,仍是Result,其實都是抽象出了Action中公共的邏輯部分,將他們放到了Action的外面,從而更加簡化了Action的開發。
3. 使得Struts2的Action看上去更像一個POJO,從而更加易於管理
Struts2的Action是一個線程安全的對象。而Web容器傳遞過來的參數,也會傳遞到Action中的成員變量中。這樣,Action看上去就更像一個POJO,從而可以方便的被許多對象容器進行管理。好比說,你能夠很是方便得把Action歸入到Spring的容器中進行管理。
數據交互上下文 ActionContext(BeatContext)
因爲Action是應對於一個又一個的URL請求,因此ActionContext應該具有如下的特性:
1. ActionContext應成爲Action與Web容器之間的橋樑
2. ActionContext中應該保存有針對某個請求的詳細信息
3. ActionContext應該是一個線程安全的類對象
攔截器和過濾器的區別:
一、攔截器是基於java的反射機制的,而過濾器是基於函數回調
二、過濾器依賴與servlet容器,而攔截器不依賴與servlet容器
三、攔截器只能對action請求起做用,而過濾器則能夠對幾乎全部的請求起做用
四、攔截器能夠訪問action上下文、值棧裏的對象,而過濾器不能
五、在action的生命週期中,攔截器能夠屢次被調用,而過濾器只能在容器初始化時被調用一次
過濾器
首先討論struts2過濾器,struts2的主要過濾器是FilterDispatcher,至關於MVC框架當中的controller,有以下幾個功能:
(1)執行Actions:過濾器經過ActionMapper對象,來判斷是否應該被映射到Action.若是mapper對象指示他應該被映射,過濾鏈將會被終止,而後Action被調用。這一點很是重要,若是同時使用SiteMesh filter,則SiteMesh filter應該放到該過濾器前,不然Action的輸出將不會被裝飾。
(2)清除ActionContext:過濾器爲了確保內存溢出,會自動的清除ActionContext。這可能會存在一些問題,在和其它的框架集成時,例如SiteMesh(一致的web頁面佈局框架,相似裝飾器)。ActionContextCleanUp提供了怎麼處理這些問題的一些信息。在配置了FilterDispatcher的前提下已經配置了ActionContextCleanUp攔截器。
(3)維護靜態內容:過濾器也會維護在Struts2中使用的一些公共的靜態的內容,例如JavaScript文件,CSS文件等。搜索/struts/*範圍內的請求,而後將/struts/後面的值映射到一些struts的公共包中,也能夠在你的類路徑中搜索。
默認狀況下會去查找如下包:org.apache.struts2.static.template。這樣你只用請求/struts/xhtml/styles.css,XHTML UI主題默認的樣式表將會被返回。一樣,AJAX UI組件須要的JavaScript文件,也能夠在org.apache.struts2.static包中被找到。若是你想加入其它被搜索的包,在web.xml中設置filter時,經過給"actionPackages"初始參數一個逗號隔開的包列表值來設定。
(4)清除request生命週期內的XWork的interceptors
自定義過濾器
應該知道若是咱們本身定義過濾器的話, 是要放在strtus2的過濾器以前的, 若是放在struts2過濾器以後,你本身的過濾器對action的過濾做用就廢了,不會有效!除非你是訪問jsp/html!
那我如今有需求, 我必須使用Action的環境,而又想在執行action以前拿filter作一些事, 用FilterDispatcher是作不到的.
那麼StrutsPrepareAndExecuteFilter能夠把他拆分紅StrutsPrepareFilter和StrutsExecuteFilter,能夠在這兩個過濾器之間加上咱們本身的過濾器.!
過濾器也能夠本身定義,在使用新的StrutsPrepareAndExecuteFilter做爲核心過濾器的狀況下,能夠將自定義的過濾器放在各類位置上。
具體的配置在web.xml當中進行配置。
攔截器
在使用攔截器的時候,在Action裏面必須最後必定要引用struts2自帶的攔截器缺省堆棧defaultStack,以下所示:
<interceptor-ref name="checkbox">
<param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>(必須加,不然出錯)
Strust2攔截器構成攔截器棧,在使用過程當中,至關於遞歸調用這些攔截器的intercept方法。一般咱們採用struts2的默認攔截器,本身開發,則要遵循如下的步驟:
1 自定義一個實現Interceptor接口(或者繼承自AbstractInterceptor)的類。
2 在strutx.xml中註冊上一步中定義的攔截器。
3 在須要使用的Action中引用上述定義的攔截器,爲了方便也可將攔截器定義爲默認的攔截器,這樣在不加特殊聲明的狀況下全部的Action都被這個攔截器攔截。
開發
Interceptor接口聲明瞭三個方法:
public interface Interceptor extends Serializable {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
Init方法在攔截器類被建立以後,在對Action鏡像攔截以前調用,至關於一個post-constructor方法,使用這個方法能夠給攔截器類作必要的初始話操做。
Destroy方法在攔截器被垃圾回收以前調用,用來回收init方法初始化的資源。
Intercept是攔截器的主要攔截方法,若是須要調用後續的Action或者攔截器,只須要在該方法中調用invocation.invoke()方法便可,在該方法調用的先後能夠插入Action調用先後攔截器須要作的方法。若是不須要調用後續的方法,則返回一個String類型的對象便可,例如Action.SUCCESS。另外AbstractInterceptor提供了一個簡單的Interceptor的實現。
註冊攔截器
<interceptors>
<interceptor name="login" class="com.jpleasure.teamware.util.CheckLoginInterceptor"/>
<interceptor-stack name="teamwareStack">
<interceptor-ref name="login"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
將上述攔截器設定爲默認攔截器
<default-interceptor-ref name="teamwareStack"/>
這樣在後續同一個package內部的全部Action執行以前都會被login攔截。
每個攔截器都有兩個默認的參數:
excludeMethods - 過濾掉不使用攔截器的方法和
includeMethods – 使用攔截器的方法。
須要說明的幾點:
1 攔截器執行的順序按照定義的順序執行
2 使用默認攔截器配置每一個Action都須要的攔截器堆棧
3 如何訪問HttpServletRequest,HttpServletResponse或者HttpSession
有兩種方法能夠達到效果,使用ActionContext:
Map attibutes = ActionContext.getContext().getSession();
或者實現相應的接口:
HttpSession SessionAware
HttpServletRequest ServletRequestAware
HttpServletResponse ServletResponseAware
集成spring與hibernate
OGNL與標籤
高級主題