1,strtus2的執行流程:
頁面form表單資料提交到name.action:
struts2的過濾器(org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter)攔截請求,尋找struts.xml檔案裡的action元素,action元素的name屬性值和form表單提交的action對應,則執行個體化action元素的class屬性值對應的類,並且將form表單提交的值通過setXxx()方法設定到class類屬性。
之後調用action類的execute方法,該方法必須返回一個字串!根據返回的字串在action元素的子項目result的name屬性name對應的值,如果匹配,則返回result元素值所指定的頁面。
通常每個action類都要繼承com.opensynphony.xwork2.ActionSupport類
2,對於自訂類型轉換器來說需要提供三個資訊:Action的名字,Action中待轉換的屬性名稱以及該屬性對應的類型轉換器。其中Action的名字是通過屬性檔案(和Action同包)來獲得的,Action中待轉換的屬性名稱是通過屬性檔案中的key值獲得的,該屬性對應的類型轉換器是通過key值所對應的value值獲得的。
3,可使用struts2架構內建的類型轉換器StrutsTypeConverter簡化類型轉換。StrutsTypeConverter繼承於DefaultTypeConverter。提供兩個抽象方法,分別為convertFromString和converToString,分別實現從頁面向後台對象轉換和從後台對象轉換成字串
4,全域類型轉換,屬性檔案在src根目錄下,屬性檔案名稱為xwork-conversion.properties。待轉換的類=轉換器的名字
struts2校正:
一編碼方式:在action中實現validate方法,該方法在ActionSupport類中是空實現,需要使用者自己繼承實現方法,定義該方法後,架構自動先執行validate方法,再執行execute方法。
struts先進行類型轉換後進行資料校正,如果在上述過程中都不會執行execute方法,頁面會轉向struts.xml中action元素名input的result指定的頁面(一般指定為輸入頁面)。如果在類型轉換時發生的錯誤,將錯誤放到fielderror中而不是actionerror中!
ActionSupport類的addActionError()方法的實現:首先建立一個ArrayList對象,然後將錯誤訊息添加到ArrayList中。
當調用getActionErrors()方法返回Action層級的錯誤資訊列表時,返回的實際是集合的一個副本,因此調用clear()方法無法清除原來集合的錯誤資訊!Action層級的錯誤資訊對開發人員來說是唯讀。
Field層級的錯誤資訊底層是用LinkedHashMap實現的,該Map的key值是String,value是一個List<String>,一個fieldname可以對應多條錯誤資訊。
如果想清除錯誤資訊:可以調用clearActionErrors(),clearFieldErrors()和clearErrors()
Action中自訂方法的輸入校正,對於通過action的method屬性所指定的自訂方法,其對應的自訂輸入校正方法名為validateMyExecute()(假設自訂方法名為myExecute),底層是通過反射來調用的。
當在action中中指定execute方法時,會先調用自訂的validate方法,然後再調用validate方法,校正過程出現任何錯誤,不會在執行execute方法。
自訂field層級的錯誤提示資訊1,建立一個以action名字命名的屬性檔案。2,然後再該屬性檔案中指定每一個出錯欄位的錯誤資訊invalid.fieldvalue.fieldname=error msg.
struts2的校正架構(一個有效xml檔案),具體來說分為欄位優校正和校正器優先校正。
對於國際化的資源檔命名規則。package_語言名(小寫)_國家名(大寫)
struts2架構校正執行的先後順序
1,首先執行校正架構,2,執行自訂方法的校正方法。
3,執行validate方法
對於struts.xml檔案的結果配置來說,局部要優於全域。
我們既可以在action中定義異常與結果,也可以定義全域的異常與結果,局部總是優先與全域的,如果定義成全域,那麼可以為所有的action所公用,而局部的異常與結果只能被當前的action所獨享,不能為其他action所使用。
sturts2的模型驅動(Model Driven),和屬性驅動的比較:
1,屬性驅動靈活,準確,模型驅動不靈活,很多時候,頁面提交過來的參數並不屬於模型中的屬性。
2,模型驅動更加符合物件導向的編程風格,使得我們獲得的是對象而不是一個離散的值。
伺服器端代碼單元測試有兩種模式:
1,容器內測試(jetty)
2,Mock測試(繼承HttpServletRequest、HttpSession、HttpServletResponse等servlet API)
Preparable介面的作用是讓Action完成一些初始化工作,這些工作放在prepare方法中執行的!
防止表單重新提交的方法:
1,通過重新導向
2,通過Session Token(Session 令牌),當用戶端請求頁面時,伺服器會通過token標籤產生一個隨機數,並且將該隨機數放置到session中,然後將隨機數發送到用戶端,當用戶端發送請求時,伺服器會接收到隨機數並且與session中所儲存的隨機數進行比較,這時兩者是相同的,伺服器就認為是第一次提交,並且更新這個隨機數,如果用戶端再重新提交,那麼用戶端發送伺服器端得還是之前那個隨機數,而伺服器端得隨機數已經變了,兩者不同,這伺服器認為是重複提交,故不成功,進而轉向invalid.token所指向的結果頁面。
攔截器(Interceptor):是sturts的核心,
1,編寫實現Interceptor介面的類
2,在struts.xml檔案中定義攔截器
2,在action中使用攔截器
一旦定義了自己的攔截器,將其配置到action上後,需要在action的最後加上預設的攔截器棧,否則預設的攔截器就失效了。
定義爛機器可以直接繼承AbstractInterceptor抽象類別(該類實現了Interceptor介面並對init和destroy方法進行了空實現)然後實現其抽象方法即可。
方法攔截器(可以對方法進行過濾攔截)
在方法過濾攔截器中,如果既沒有指定includeMethods參數,也沒有指定execludeMethods,所有的方法都會被攔截。如果只指定了includeMethods參數,只攔截包含的方法。
package元素的abstract屬性工作表示該包是抽象的,不能直接使用,需要由子包繼承。如struts-default包。
package元素的namespace屬性起到命名空間分割的作用,通常將namespace的值設定為目錄的名字。
檔案上傳:
進行檔案上傳時,必須將表單的method屬性設定為post,將enctype屬性設定為multipart/form-data.
struts2檔案上傳:首先將用戶端上傳的檔案儲存到struts.multipart.saveDir鍵所指定的目錄中,如果該鍵所對應的目錄不存在那麼就儲存到javax.servlet.context.tempdir環境變數指定的目錄中。
action中所定義的File類型變數file實際上指向的是臨時目錄中的臨時檔案,然後再伺服器端通過IO寫入指定目錄。