標籤:struts2
一、struts2的核心組件
(1)Configuration
(2)Action
(3)Interceptor
(4)Value Stack / OGNL
(5)Result Types
(6)Results / View Technology
二、architectural goals:
(1)separation of concerns
(2)loose coupling
(3)testability
(4)modularization
(5)convention over configuration
1.在Action中訪問Web資源:
(1)什麼是WEB資源?
HttpServletRequest 、HttpSession 、ServletContext 等原生的 Servlet API
(2)為什麼訪問WEB資源?
B/S 的應用的 Controller 必須要訪問 WEB 資源:向域對象中讀寫屬性,讀寫 Cookie,擷取 realPath。。。
(4)如何訪問?
I.和 Servlet API 解耦的方式:只能訪問有限的 Servlet API對象,且只能訪問其有限的方法(讀取請求參數,讀寫域對象的屬性,使 Session 失效。。。)
> 使用 ActionContext
> 實現 XXXAware 介面
> 選用建議:若一個 Action 類中有多個 action 方法,且多個方法都需要使用域對象的 Map 或 parameters,則建議使用 Aware 介面的方式
> session 對應的 Map 實際上是 SessionMap 類型
II.和 Servlet API 耦合的方式:可以訪問更多的 Servlet API 對象,且可以調用其原生的方法
> 使用 ServletActionContext > 使用 ServletXXXAware 介面
2.struts.properties struts.xml主要負責管理應用中的Action映射,以及該Action包含的Result定義等。除此之外,還包含一個struts.properties檔案:定義struts2架構的大量屬性,開發人員可以通過改變這些屬性來滿足應用的需求。 struts.properties檔案通常放在WEB-INF/classes路徑下,其實,它的內容均可以在struts.xml中以<constant name="" value=""></constant>載入,或者在web.xml中以<init-param>標籤載入。
3.struts.xml 在其中的action結點(請求與Action類的映射),可以通過 annotation 、web.xml startup parameters 和 alternate URL mapping schemes來代替。 但是如果需要解決global results,exception handling和自訂攔截器棧,則必須要用strusts.xml struts-default.xml和strut.plugin.xml被自動包含進來。前者提供strust2架構的核心配置,後者提供特殊外掛程式的配置。每一個plug-in jar檔案都應該包含一個struts-plugin.xml檔案 (1)<struts>標籤:包含其他所有的標籤 (2)<include>標籤:引用一個其他的設定檔 (3)<package>標籤:屬性abstract為true時,該標籤內不能配置action;繼承自struts-default package
4.Result Types (1)dispatcher類型 最常用 後台使用HttpServletRequest的RequestDispatcher來轉寄請求 > 實作類別:org.apache.struts2.dispatcher.ServletDispatcherResult > 兩個屬性
<result name="success" type="dispacther"> <param name="location">/success.jsp</param> //指定Action執行完畢後要轉向的目標資源 <param name="parse">true</param> //true:解析location參數中的OGNL運算式;反之則不解析 </result>
(2)redirect類型 後台使用HttpServletResponse的sendRedirect方法來請求重新導向到指定的URL > 實作類別:org.apache.struts2.dispatcher.ServletRedirectResult > 兩個屬性:同上 > 適用場合:使用者註冊、線上調查等,不會造成重新整理導致的重複提交問題(3)redirectAction類型 > 實作類別:org.apache.struts2.dispatcher.ServletActionRedirectResult(繼承自ServletRedirectResult) > 工作原理同redirect一樣,區別是重新定向到另外一個action(4)plainText類型 > 實作類別:org.apache.struts2.dispatcher.PlainTextResult > 可以輸出JSP或HTML原始碼 > struts2架構自動完成對標記到實體引用或者字元引用的轉換 > 兩個屬性:location和charSet,後者代表輸出頁面內容時使用的字元編碼(5)全域結果 > 在<global-results>標籤內使用(6)動態結果 > 配置的時候不知道要執行哪一個結果,配置結果時使用了運算式,運行時架構解析運算式,根據運算式的值來確定要執行的結果 > 在結果映射中,使用${...}文法訪問的屬性一定要在Action中存在,提供對應的JavaBean風格的getter方法。在JavaBean中執行個體變數名和屬性名稱可以不同,使用${...}訪問的是屬性名稱
5.Interceptors(1)要使某個攔截器能被需要它的Action使用,有兩種配置方法: > 該方法沒有攔截器配置的數量限制,唯一要求的是,攔截器的執行順序就是在Action中配置的順序
<interceptors> … <interceptor name="autowiring" class="interceptor.ActionAutowiringInterceptor"/> </interceptors> <action name="my" class="com.fdar.infoq.MyAction" > <result>view.jsp</result> <interceptor-ref name="autowiring"/> </action>
> 在</package>之前使用<default-interceptor-ref name="autowiring"/>,但是只有一個攔截器才能被定義為預設的攔截器(2)攔截器棧的表示和使用
<interceptor-stack name="basicStack"> <interceptor-ref name="exception"/> <interceptor-ref name="servlet-config"/> <interceptor-ref name="prepare"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/></interceptor-stack><action name="my" class="com.fdar.infoq.MyAction" > <result>view.jsp</result> <interceptor-ref name="basicStack"/></action>
(3)ActionInvocation提供了可以訪問運行環境的許可權(4)struts2將它的核心功能放到攔截器中實現,而不是分散到Action中實現,有利於系統的解耦,使得功能的實作類別似於個人電腦的組裝,變成了可插拔的:需要某個功能就插入一個攔截器,不需要某個功能就拔出一個攔截器。你可以任意組合攔截器來為Action提供附加功能,而不需要修改Action(5)實現Interceptor介面: >init >destroy >intercept:在Action執行前被調用,攔截器為Action提供的附加功能在這裡實現。 利用invocation參數可以擷取Action執行的狀態。如果要繼續執行後續部分(餘下的攔截器、Action、Result)可以調用invocation.invoke();如果要終止後續的執行,可以直接返回一個結果碼,架構將根據這個結果碼來呈現對應的結果檢視(6)攔截器執行順序:我們可以以invocation.invoke()為界,將攔截器中的代碼分成2個部分,在invocation.invoke()之前的代碼,將會在Action之前被依次執行,而在invocation.invoke()之後的代碼,將會在Action之後被逆序執行。 【計算Action執行時間的執行個體】:
public String intercept(ActionInvocation invocation){ long startTime=System.currentTimeMillis(); String result=invocation.invoke(); //攔截點 long executionTime=System.currentTimeMillis()-startTime; System.out.println("Action的執行花費的毫秒數是:"+exexutionTime); return result;}
(7)MethodFilterInterceptor可以指定要攔截或者排除的方法列表,通過指定included和excluded方法列表來實現,例如:
public String intercept(ActionInvocation invocation){ long startTime=System.currentTimeMillis(); String result=invocation.invoke(); //攔截點 long executionTime=System.currentTimeMillis()-startTime; System.out.println("Action的執行花費的毫秒數是:"+exexutionTime); return result;}
(8)攔截器必須是無狀態的,換句話說,在攔截器類中不能有執行個體變數。(9)如果包繼承自struts-default包,那麼defaultStack攔截器棧將是預設的攔截器引用(10)PreResultListener介面 >在Action執行之後、Result執行之前得到通知,從而在視圖呈現給使用者之前做一些處理 >執行個體需要手工註冊,在攔截器調用invocation.invoke()方法之前調用invocation.addPreResultListener()方法註冊PreResultListener
6.Value Stack/ OGNL > Value Stack : a stack of objects > OGNL:access objects within the value stack (1)Value Stack中Object的種類及順序 > Temporary Objects > The Model Object > The Action Object:the action being executed > The Named Objects:#application #request #session #attr #parameters(2)strust2的值棧允許存在許多虛擬根對象:將OGNL上下文設定為ActionContext,並將值棧作為OGNL的根對象(3)top 結合 [N].xx文法可以訪問棧中的任意對象(4)struts2架構總是把Action執行個體放置在棧頂,因為在Action在值棧中,而值棧又是OGNL的根,所以引用Action的屬性可以省略#標記(5)struts2中的命名物件 > #parameters.XX 或者 #parameters[‘XX]]:用於訪問請求參數,本質上parameters是一個Map對象,用HttpServletRequest對象中的請求參數構造的,一旦對象建立好了(在Action執行個體之前就建立好了),它和HttpServletRequest就沒有關係了,所以唯讀不可寫(寫了沒有效果) > #request > #session > #application > #attr:PageContext(6)值棧能夠安全執行緒地為每個請求提供公用的資料存取服務 > 當有請求到達時,struts2會為每個請求建立一個新的值棧,也就是說,值棧和請求是一一對應的,不同的請求,值棧也不一樣,而值棧封裝了一次請求所有需要操作的相關資料(7)怎麼講struts2值棧中的對象刪除?
> ValueStack 對象。這個對象貫穿整個 Action 的生命週期(每個 Action 類的對象執行個體會擁有一個 ValueStack 對象)。當 Struts 2 接收到一個 .action 的請求後,會先建立 Action 類的對象執行個體,但並不會調用 Action 方法,而是先將 Action 類的相應屬性放到 ValueStack 對象的頂層節點( ValueStack 對象相當於一個棧)。
所以刪除操作不了。
7.OGNL(1)為什麼使用OGNL? > 取代Java代碼 > 簡化資料訪問的方式 > 提供更清晰的視圖層實現(2)OGNL運算式的計算都是圍繞OGNL上下文來進行的,OGNL上下文實際上是一個Map對象,它可以包含許多JavaBean對象,這些對象中有一個特殊的根對象。(3)運算式的基礎單元:導航鏈(4)OGNL提供調用任何方法的能力(5)調用靜態方法:@[email protected](6)調用構造方法:new ,必須使用完整的限定類名(7)投影、選擇
8.標籤(1)通用標籤 >資料標籤 >控制標籤(2)UI標籤 >表單標籤 >非表單標籤 >Ajax標籤