action元素指定method屬性
對action進行如下的配置:
<action name=”Login” class=”cc.dynasoft.LoginAction” method=”login” />
……
</action>
<action name=”Regist” class=”cc.dynasoft.LoginAction” />
……
</action>
查看以上兩個action,默認的情況是Regist,而當Login的時候,將提交到LoginAction的login中。查看上面的兩個action,class都是一樣的,於是就出現了下面的使用通配符的概念。
使用通配符
在配置action的時候,action的三個屬性name、class和method都可以使用通配符。
以下舉例說明:
例1:<action name=”*Action” class=”cc.dynasoft.LoginAction” method=”{1}”>
……
</action>
解釋一下上面代碼的含義:上面定義的不是一個普通的action,而是定義了一系列的action,只要URL是*Action.action的模式,都可以通過該Action進行處理。但該Action定義了一個表達式{1},該表達式的值就是name屬性值中的第一個*的值。
例如,如果用戶請求的URL是loginAction.action,則調用該action的login方法;如果用戶請求的URL是registAction.action,則調用該action的regist方法。
例2:<action name=”*Action” class=”cc.dynasoft.{1}Action”>
……
</action>
比如說:如果URL爲RegistAction.action,可以匹配上面的action,該action的處理類是cc.dynasoft.RegistAction
例3:<action name=”*_*” class=”cc.dynasoft.{1}Action” method=”{2}”>
當一個action爲Book_save.action的時候將調用BookAction的save方法來處理用戶請求。
注意這個時候指定校驗文件需要注意,比如說Book_save.action的校驗文件應該是
Book_save-validation.xml。
例4:<action name=”*”>
<result>/{1}.jsp</result>
</action>
這個應該不難理解,呵呵。
以下需要注意的問題:
如果有URL爲abcAction.action的請求,如果struts.xml文件有名爲abcAction的Action,則一定由該Action來處理用戶請求;如果struts.xml文件沒有名爲abcAction的Action,則搜索name屬性值匹配abcAction的Action,例如name爲*Action或*,*Action並不會比*更優先匹配abcAction的請求,而是先找到哪個Action,就先由哪個Action來處理用戶的請求。因此,我們應該將名爲*的Action配置在最後,否則struts2將使用該Action來處理所有希望使用模式匹配的請求。
處理結果
struts2通過在struts.xml文件中使用<result>元素來配置結果,根據<result>元素所在位置的不同,struts2提供了兩種結果。
局部結果:將<result>作爲<action>元素的子元素配置
全局結果:將<result>作爲<global-result>元素的子元素配置。
以下列出比較標準的配置:
<result name=”success” type=”dispatcher”>
<param name=”location” >/thank_you.jsp</param>
<param name=”parse” >true</param>
</result>
location:用於指定實際視圖資源
parse:該參數指定是否允許在實際視圖名稱中使用ONGL表達式,默認爲true。如果設置爲false則不允許使用,通常不需要修改。
一般我們比較常用的寫法:
<result name=”success” type=”dispatcher”>
/thank_you.jsp
</result>
注意如果沒有指定name屬性:則默認是success;如果沒有指定type,則默認就是dispatcher,即JSP。
下面列出struts2內建支持的結果類型如下:
chain:Action鏈式處理的結果類型,也就是將結果轉發到這個action中。
chart:整合JFreeChart的結果類型
dispatcher:用於整合JSP的結果類型
freemarker:用於整合freemarker結果類型。
httpheader:用於控制特殊的HTTP行爲的結果類型。
jasper:用於JasperReports整合的結果類型
jsf:用於整合JSF後的結果類型
redirect:實際上dispatcher和redirect的區別就是在於轉發和重定向的區別。
redirect-action:用於直接redirect action。
stream:用於向瀏覽器返回一個Inputstream(用於文件下載)
tiles:用於整合Tiles後的結果類型。
velocity:用於整合Velocity的結果類型。
xslt:用於整合XML/XSLT的結果類型。
plaintext:用於顯示某個頁面的源代碼。
plaintext、redirect以及redirect-action的配置分別如下:
<result type=”plaintext”>
<param name=”location”>/welcome.jsp</param>
<!—設置字符集編碼-->
<param name=”charset”>gb2312</param>
</result>
<result type=”redirect”>
/welcome.jsp
</result>
<result type=” redirect-action”>
<!—指定action的命名空間-->
<param name=”namespace”>/ss</param>
<!—指定action的名字-->
<param name=”actionName”>login </param>
</result>
在請求結果中使用ONGL表達式
例子:
<result type=”redirect”>edit.action?skillName=${currentSkill.name}</result>
對於上面的表達式語法,要求action中必須包含currentSkill屬性,並且currentSkill屬性必須包含name屬性,否則${currentSkill.name}表達式值爲null。
屬性驅動和模型驅動
我不推薦使用模型驅動,屬性驅動完全可以實現模型驅動的效果。
異常處理
異常處理在struts2中採用可配置的方式來處理,主要是爲了防止異常代碼和action代碼耦合。我們比較希望的異常處理模式是這樣的,如果出現了異常一,則系統跳轉到視圖1;如果出現了異常二,則系統轉到視圖2。
我們查看execute的聲明:public String execute() throws Exception可以發現將異常拋出由struts2框架進行處理,爲了處理異常,我們必須使用exception攔截器,由於在struts-default.xml的defaultStack中已經存在這個攔截器的定義,於是我們可以不用做任何事情。
struts2的異常處理機制是通過在struts.xml文件中配置<exception-mapping />元素完成的,配置該元素的時候,需要指定兩個屬性:
exception:此屬性指定該異常映射所設置的異常類型。
result:出現這個異常的時候,轉入result屬性所指向的結果。
根據<exception-mapping />元素出現的位置的不同,異常映射又可分爲兩種:
局部異常映射:將<exception-mapping />作爲action的子元素配置
全局異常映射:將<exception-mapping />元素作爲<global-exception-mappings>元素的子元素配置。
實際上配置類似result,可以有局部,也可以是全局,局部優先。
舉個例子:
<global-exception-mappings>
<exception-mapping exception=”java.sql.SQLException” result=”sql”/>
<exception-mapping exception=”java.lang.Exception” result=”root”/>
</ global-exception-mappings>
注意以上的sql和root是全局result。
輸出異常信息:
<s:property value=”exception” />:輸出異常對象本身,注意這個異常代表Exception的實例,因此可以調用message屬性。
<s:property value=”exceptionStack” />:輸出異常堆棧信息。