米洗畢,水適量,蓋合上,心搖擺,總覺水多了一分或是少了幾點,於是重又 加上或倒出少許,其實這丁點份量完全無礙煮出香噴噴的飯來。及至將熟之際, 亦有猶豫,心中默數至少10,如再有不定辄至20,掐火,20對最終質量來說或有 所損。
1. Struts2 的 Action 中可直接用屬性來封裝請求參數和處理結果,此謂之 屬性驅動。也可以像 Struts1 那樣使用專門的 ActionForm 來處理請求參數和結 果,只不過 Struts2 用的是一個更單純的 POJO,這就做模型驅動;此時的 Action 需要實現 ModelDriven 接口,並實現其 getModel() 方法將 Action 與 對應 Model 相關聯。
2. 例子說明采用模型驅動的 Action (UserBean 是一個普通 JavaBean,其中 定義了 username 和 password 兩個屬性):
public class LoginAction implments Action, ModelDriven<UserBean>{
UserBean model = new UserBean();
public UserBean getModel(){
return model;
}
}
上面例子使用了泛型,Struts2 的 Action 要使用一個模型不需要在配置文 件中作額外的配置。
3. 請求參數自動封裝到模型中是由配置 struts-default.xml 中的 ModelDrivenIntercepter 來完成的。要輸出模型中值時用標記 <s:property value="model.username"/>。而倘若寫成了<s:property value="username"/>,Struts2 也會作智能處理,要是這個 Action 中未定義 username 屬性,並且彩用了模型驅動模式,也會輸出模型 model.username 屬性 ,就像 Struts1 顯示 ActionForm 一樣可不寫 name 屬性。
4. Struts2 的異常處理,基本和 Struts1 一樣的思維,都提供了聲明式異常 處理方式,在 struts.xml 中配置。Struts2 的 <global-exception- mappings .../>、<exception-mapping .../> 分別與 Struts1 的 <global-exceptions .../>、<exception .../> 對應,作用都是聲 明 Action 中出現何種類型的異常,轉到對應頁面,你的 Action 的 execute() 方法只管 throws Exception 就行,剩下的事框架幫你處理。
5. 異常信息的輸出,<s:property value="exception"/> 輸出異常對 象本身;<s:property value="exceptionStack"/> 輸出異常堆棧信息,這 是 Struts1 沒有的功能;<s:property value="exception.message"/> 輸 出異常的 message 屬性。至於標簽輸出異常國際化消息,可就要借鑒前面的知識 稍加斟酌一番,其實就是:如 execute() throw new Exception("name.error") ,要輸出 name.error 對應消息用 <s:property value="%{getText (exception.message)}"/> 即可,如果找不到 name.error 對應消息,會直接 把 "name.error" 原本輸出。
6. 頁面請求數據或待顯示的結果(它們總是字符串)與Java對象之間要一個類 型轉換器,例如,"2007-01-01" 提交後就是一個 Date 對象,"Unmi,000" 一提 交就是一個 UserBean 對象("Unmi"和"000"分別對應 UserBean 的用戶名和密碼) ,用 <s:property value="userbean"/> 顯示這個 UserBean 對象形式為 "Unmi,000"。可想而知,Struts2 肯定為我們內置了不少類型轉換器。
7. 可以自定義類型轉換器,實現 TypeConverter 接口或繼承 DefaultTypeConverter 類。一般采用繼承的方法。注意 DefaultTypeConverter 的 ObjectconvertValue(map context, Object value, Class toType) 方法的寫 法,了解該方法的參數及返回值的類型與意義;該方法中依據 toType 的類型分 別實現兩個方向的轉換邏輯,如果是從請求到 Java 對象的轉換時,value 參數 是一個字符串數組,實質是用 request.getParameterValues(name) 獲取的值。
8. 自定義的類型轉換器可注冊為局部的(為某些個 Action 所用)或全局的(為 所有 Action 所用)。局部類型轉換器的注冊方式是提供一個名為 ActionName- conversion.properties 放在該 Action 的 class 所在路徑下(記得校驗文件也 是放在同樣的位置)。這個文件的內容格式為:
Action中的屬性名=類型轉換器的全限類名
例如:
user=com.unmi.struts2.converter.UserConverter
user 該 Action 中的屬性的名稱,對該 Action 中的 user 屬性用 UserConverter 轉換。可有多行,分別為不同的屬性設置轉換器。
9. 注冊為全局的類型轉換器的方法。提供一個 xwork-conversion.property 放在 classpath 下(基本就是 WEB-INF/classes 下),然後裡面可加多個 "屬性 類型=類型轉換器的全限類名"。如
com.unmi.vo.User=com.unmi.struts2.converter.UserConverter
com.unmi.vo.User 為 Action 中的屬性類型,碰到 User 類型屬性就用 UserConverter 轉換。可有多行,分別用於轉換不同的屬性類型。
10. 再回過頭來與 Struts1 作個對比,Struts1 的類型轉換器只能注冊全局 的,而不能只為個別 Action 服務,並且要通過編寫代碼來注冊,注冊代碼如下 :
ConvertUtils.register(new DateConverter(), Date.class);