1)在軟體設計上Struts2的應用可以不依賴於Servlet API和struts API。 Struts2的這種設計屬於無侵入式設計;
2)攔截器,實現如參數攔截注入等功能;
3)類型轉換器,可以把特殊的請求參數轉換成需要的類型;
4)多種表現層技術,如:JSP、freeMarker、Velocity等;
5)Struts2的輸入校正可以對指定某個方法進行校正;
6)提供了全域範圍、包範圍和Action範圍的國際化資源檔管理實現
struts2架構是通過Filter啟動的,即StrutsPrepareAndExecuteFilter,此過濾器為struts2的核心過濾器;
StrutsPrepareAndExecuteFilter的init()方法中將會讀取類路徑下預設的設定檔struts.xml完成初始化操作。struts2讀取到struts.xml的內容後,是將內
容封裝進javabean對象然後存放在記憶體中,以後使用者的每次請求處理將使用記憶體中的資料,而不是每次請求都讀取struts.xml檔案
--------web.xml載入StrutsPrepareAndExecuteFilter
---------調用ActionMapper該request是否需要struts2進行處理
----------如果需要則將請求交給ActionProxy處理,ActionProxy根據配置manager和ActionMapper來分析執行的具體action
----------然後ActionProxy會執行個體化一個ActionInvocation執行個體調用真正的ation類
-----------初始化ActionInvocation執行個體時會根據設定檔載入對應的interceptor
-----------最後返回ActionInvocation返回對應的result根據struts.xml設定檔返回對應頁面到瀏覽器,或者返回action則整個流程迴圈執行
- struts2架構的核心控制器是什嗎?它有什麼作用?
1)Struts2架構的核心控制器是
StrutsPrepareAndExecuteFilter。(
struts2.1.3之前是filterdispatcher)
2)作用:
負責攔截由<url-pattern>/*</url-pattern>指定的所有使用者請求,當使用者請求到達時,該Filter會過濾使用者的請求。預設情況下,如果使用者請求的路徑
不帶尾碼或者尾碼以.action結尾,這時請求將被轉入struts2架構處理,否則struts2架構將略過該請求的處理。
可以通過常量"struts.action.extension"修改action的尾碼,如:
<struts><constant name="struts.action.extension" value="do"/></struts>
如果使用者需要指定多個請求尾碼,則多個尾碼之間以英文逗號(,)隔開。如:
<constant name="struts.action.extension" value="do,go"/>
struts.xml ——> struts.properties
常量可以在struts.xml或struts.properties中配置,如果在多個檔案中配置了同一個常量,則後一個檔案中配置的常量值會覆蓋前面檔案中配置的常量值.
struts.xml檔案的作用:通知Struts2架構載入對應的Action資源--------------一般struts.properties設定檔不用,直接在struts.xml中配置常量
常量可以在struts.xml或struts.properties中配置,兩種配置方式如下:
1)在struts.xml檔案中配置常量
<struts>
<constant name="struts.action.extension" value="do"/>
</struts>
2)在struts.properties中配置常量(struts.properties檔案放置在src下):
struts.action.extension=do
- struts2如何訪問HttpServletRequest, HttpSession 和 ServletContext三個域對象?
方案一:
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session =
request.getSession();
ServletContext servletContext =
ServletActionContext.getServletContext();
方案二:
類
implements ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware
注意:架構自動傳入對應的域對象
- struts2是如何管理action的?這種管理方式有什麼好處?
struts2架構中使用包來管理Action,包的作用和java中的類包是非常類似的。
主要用於管理一組業務功能相關的action。在實際應用中,我們應該把一組業務功能相關的Action放在同一個包下。
struts2中的預設包struts-default有什麼作用?
1)struts-default包是由struts內建的,它定義了struts2內部的眾多攔截器和Result類型,而Struts2很多核心的功能都是通過這些內建的攔截器實現,如:從請求中
把請求參數封裝到action、檔案上傳和資料驗證等等都是通過攔截器實現的。當包繼承了struts-default包才能使用struts2為我們提供的這些功能。
2)struts-default包是在struts-default.xml中定義,struts-default.xml也是Struts2預設設定檔。 Struts2每次都會自動載入 struts-default.xml檔案。
3)通常每個包都應該繼承struts-default包,
struts2的工作流程?
使用者請求
——> StrutsPrepareAndExecuteFilter
——> Interceptor
——> Action
——> Result
——> Jsp/html
——> 響應
struts2的action的URL訪問路徑由什麼構成?
由兩部分組成:包的命名空間+action的名稱 [ + action的尾碼 ],即:package.namespace + action.name
在struts.xml中可以不為action指定class屬性嗎?struts2中有哪些預設的屬性?
可以,如果沒有為action指定class,預設是com.opensymphony.xwork2.ActionSupport
預設屬性:
如果沒有為action指定class ActionSupport
如果沒有為action指定method execute() 注意:ActionSupport的execute方法裡面就一句話return "success";
如果沒有指定result的name success
如果沒有指定result的type dispatcher
action中預設都有一個攔截器的引用,即:<interceptor-ref name="defaultStack">;
注意:
1)一旦我們為該包中的某個action顯式指定了某個攔截器,則預設攔截器不會起作用,所以此時要顯式的引進預設的攔截器;
2)每個包只能指定一個預設攔截器,每個預設攔截器只針對當前包下有效。
struts2如何對指定的方法進行驗證?
1)validate()方法會校正action中所有與execute方法簽名相同的方法;
2)要校正指定的方法通過重寫validateXxx()方法實現, validateXxx()只會校正action中方法名為Xxx的方法。其中Xxx的第一個字母要大寫;
3)當某個資料校正失敗時,調用addFieldError()方法往系統的fieldErrors添加校正失敗資訊(為了使用addFieldError()方法,action可以繼承ActionSupport),
如果系統 的fieldErrors包含失敗資訊,struts2會將請求轉寄到名為input的result;
4)在input視圖中可以通過<s:fielderror/>顯示失敗資訊。
5)先執行validateXxxx()->validate()->如果出錯了,會轉寄<result name="input"/>所指定的頁面,如果不出錯,會直接進行Action::execute()方法
struts2預設能解決get和post提交方式的亂碼問題嗎?
不能。struts.i18n.encoding=UTF-8屬性值只能解析POST提交下的亂碼問題。
struts2如何完成檔案的上傳?
1、JSP頁面:
1)JSP頁面的上傳檔案的組件:<s: file name=”upload” />,如果需要一次上傳多個檔案, 就必須使用多個 file 標籤, 但它們的名字必須是相同的,即:
name=“xxx”的值必須一樣;
2)必須把表單的enctype屬性設定為:multipart/form-data;
3)表單的方法必須為post,因為post提交的資料在訊息體中,而無大小限制。
2、對應的action:
1)在 Action 中新添加 3 個和檔案上傳相關的屬性;
2)如果是上傳單個檔案, uploadImage屬性的類型就是 java.io.File, 它代表被上傳的檔案, 第二個和第三個屬性的類型是 String, 它們分別代表上傳文
件的檔案名稱和檔案類型,定義方式是分別是:
jsp頁面file組件的名稱+ContentType,
jsp頁面file組件的名稱+FileName
3)如果上上傳多個檔案, 可以使用數組或 List
struts2的攔截器與攔截器棧有什麼區別:
1)Struts2 攔截器在訪問某個 Action 方法之前或之後實施攔截, Struts2 攔截器是可插拔的。
2)攔截器棧(Interceptor Stack): 將攔截器按一定的順序連接成一條鏈,在訪問被攔截的方法時, Struts2攔截器鏈中的攔截器就會按其之前定義的順序被依次
調用,類似於Filter在web.xml檔案中的配置順序調用。
攔截器的生命週期與工作過程?
1)每個攔截器都是實現了Interceptor介面的 Java 類;
2)init(): 該方法將在攔截器被建立後立即被調用, 它在攔截器的生命週期內只被調用一次. 可以在該方法中對相關資源進行必要的初始化;
3)intercept(ActionInvocation invocation): 每攔截一個動作請求, 該方法就會被調用一次;
4)destroy: 該方法將在攔截器被銷毀之前被調用, 它在攔截器的生命週期內也只被調用一次;
5)struts2中有內建了18個攔截器。
攔截器的作用?攔截器與過濾器的區別?
1)攔截器是對調用的Action起作用,它提供了一種機制可以使開發人員可以定義在一個action執行的前後執行的代碼。攔截器只能攔截Action,說明白點攔截器其實是Action
的功能塊,只在Action前後執行。攔截器可以抽象出一部分代碼可以用來完善原來的action。同時可以減輕代碼冗餘,提高重用率。
2)過濾器是攔截使用者請求的,範圍明顯比攔截器大的多。
請你寫出struts2中至少5個的預設攔截器?
fileUpload 提供檔案上傳功能
i18n 記錄使用者選擇的locale
cookies 使用配置的name,value來是指cookies
checkbox 添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定為false,而html預設情況下不提交沒有選中的checkbox。
chain 讓前一個Action的屬性可以被後一個Action訪問,現在和chain類型的result()結合使用。
alias 在不同請求之間將請求參數在不同名字件轉換,請求內容不變
result的type屬性中有哪幾種結果類型?
一共10種:
dispatcher struts預設的結果類型,把控制權轉寄給應用程式裡的某個資源不能把控制權轉寄給一個外部資源,若需要把控制權重新導向到一個外部資源, 應該使用
redirect結果類型
redirect 把響應重新導向到另一個資源(包括一個外部資源)
redirectAction 把響應重新導向到另一個 Action
freemarker、velocity、chain、httpheader、xslt、plainText、stream
struts2如何完成從html表單到action的類型轉換?
1)在 struts2 中, 把請求參數映射到 action 屬性的工作由 Params攔截器負責, 它是預設的 defaultStack 攔截器中的一員. Params攔截器可以自動完成字串
和基礎資料型別 (Elementary Data Type)之間轉換.
2)對於參考型別的資料(除String、Collection)轉換,需要自訂類型轉換器;
3)自訂類型轉化器必須實現TypeConverter 介面或對這個介面的某種具體實現做擴充,如:StrutsTypeConverter,重寫convertToString和convertFromString方法;
4)兩種自訂類型的轉換器:
>> 局部:
建立一個屬性檔案: ActionClassName-conversion.properties, 該檔案需和相對應的動作類(Action)放在同一個目錄下, ActionClassName是Action的類名,
後面的-conversion.properties 是固定寫法。在properties檔案中的內容為: 屬性名稱=類型轉換器的全類名
>> 全域:
在 WEB-INF/classes/ 目錄下建立 xwork-conversion.properties 檔案. 在properties檔案中的內容為: 待轉換的類型=類型轉換器的全類名
注意:對於轉換的是屬性,只需要寫屬性名稱,如果是對應的是類型,則需要寫全類名
值棧ValueStack的原理與生命週期?
1)ValueStack貫穿整個 Action 的生命週期,儲存在request域中,所以ValueStack和request的生命週期一樣。當Struts2接受一個請求時,會迅速建立ActionContext,
ValueStack,action。然後把action存放進ValueStack,所以action的執行個體變數可以被OGNL訪問。 請求來的時候,action、ValueStack的生命開始,請求結束,action、
ValueStack的生命結束;
2)action是多例的,和Servlet不一樣,Servelt是單例的;
3)每個action的都有一個對應的值棧,值棧存放的資料類型是該action的執行個體,以及該action中的執行個體變數,Action對象預設儲存在棧頂;
4)ValueStack本質上就是一個ArrayList;
5)關於ContextMap,Struts 會把下面這些映射壓入 ContextMap 中:
parameters : 該 Map 中包含當前請求的請求參數
request : 該 Map 中包含當前 request 對象中的所有屬性
session : 該 Map 中包含當前 session 對象中的所有屬性
application : 該 Map 中包含當前 application 對象中的所有屬性
attr : 該 Map 按如下順序來檢索某個屬性: request, session, application
6)使用OGNL訪問值棧的內容時,不需要#號,而訪問request、session、application、attr時,需要加#號;
7)注意: Struts2中,OGNL運算式需要配合Struts標籤才可以使用。如:<s:property value="name"/>
8)在struts2設定檔中引用ognl運算式 ,引用值棧的值 ,此時使用的"$",而不是#或者%;
ActionContext、ServletContext、pageContext的區別?
1)ActionContext是當前的Action的上下文環境,通過ActionContext可以擷取到request、session、ServletContext等與Action有關的對象的引用;
2)ServletContext是域對象,一個web應用中只有一個ServletContext,生命週期伴隨整個web應用;
3)pageContext是JSP中的最重要的一個內建對象,可以通過pageContext擷取其他域對象的應用,同時它是一個域對象,作用範圍只針對當前頁面,當前頁面結束時,pageContext銷毀,
生命週期是JSP四個域對象中最小的。
struts2如何防止使用者表單重複提交?
第一步:在表單中加入<s:token />
第二步,使用token欄截器,定義invalid.token結果集