Struts2 動態Action的三種實現方法
備註:原文不詳,故無法貼網址
最早使用動態方式呼叫是在spring中,沒想到Struts2也支援動態方法呼叫了,真是方便不少啊,呵呵,下面就來說說吧 :-)
1.動態方法呼叫
Struts2支援動態方法呼叫,它指的是一個Action中有多個方法,系統根據表單元素給定的action來訪問不同的方法,而不用寫多個Action。
使用動態方法呼叫前必須設定Struts2允許動態方法呼叫,它是通過設定
struts.enable.DynamicMethodInvocation = true來完成的。
Struts2有多種方式實現動態方法呼叫(以下action
(1). 修改頁面Form的action請求方式
將頁面上action的請求方式改為:action = “ActionName!MethodName.do”,示例:
Login.jsp
……
var contextPath = “<%=request.getContextPath()%>”;
<script type=”text/JavaScript”>
function dynamicMethodInvoke(){
document.forms[0].action = contextPath + “Login!dynamicMethod.do”;
document.forms[0].submit();
}
</script>
……
<input type=”button” value=”動態方法呼叫” onclick=”dynamoicMethodInvoke()”/>
……
當點選“動態方法呼叫”按鈕時,執行dynamoicMethodInvoke方法,在此方法中修改提交的action為Login!dynamicMethod.do,它的意思是將表單提交給Login Action的dynamicMethod方法進行處理。
LoginAction.Java
public class LoginAction {
……
public String dynamicMethod() throws Exception{
……
return “success”;
}
public String execute() throws Exception{
……
if (…){
return “error”;
}
……
return “success”
}
}
通過這種方式,可以在一個Action中包含多個方法,通過指定不同的action屬性來提交給Action的不同方法進行處理。
對於使用動態方法呼叫的方法,它的宣告與系統預設的execute方法的方法宣告只有方法名不同,其他的如引數、返回值型別都必須相同。
(2). 指定action的method屬性
另一種動態呼叫方式是在struts.xml中指定action的method屬性,這樣可以讓Action類呼叫指定方法,而不是預設的execute方法來處理請求。示例:
struts.xml
……
<package name=”demo1” extends=”struts-default”>
<action name=”Login” class=”com.demo.LoginAction” />
<result name=”input”>/input.jsp</result>
<result name=”error”>/error.jsp</result>
<result name=”success”>/success.jsp</result>
</action>
<action name=”Registry” class=”com.demo.LoginAction” method=”registry” />
<result name=”input”>/input.jsp</result>
<result name=”error”>/error.jsp</result>
<result name=”success”>/success.jsp</result>
</action>
</package>
上述配置中兩個action的實現類均為com.demo.LoginAction,他們的實現類雖然相同,但處理邏輯卻不同,處理邏輯通過method方法指定,其中名為Login的Action對應的處理邏輯為預設的execute方法,而名為Registry的Action對應的處理邏輯則為method指定的registry方法。
(3). 使用萬用字元
仔細看上面struts.xml中兩個action的定義,可以發現他們除了name和method屬性不同以外,其餘的都一樣,這種定義相當的冗餘,為了解決這種型別的問題,Struts2提供了萬用字元定義方式。
在配置<action/>元素時,需要指定name、class、method等屬性,這3個屬性都支援萬用字元,在使用萬用字元定義Action的name屬性時,相當於一個元素action定義多個邏輯Action。(2)中的action配置可以更改為:
<package name=”demo” extends=”struts-default”>
<action name=”*Action” class=”com.demo.LoginAction” method=”{1}”>
<result name=”input”>/input.jsp</result>
<result name=”error”>/error.jsp</result>
<result name=”success”>/success.jsp</result>
</action>
</package>
上述定義不是定義了一個普通的action,而是定義一系列的action,只要使用者請求的URL滿足*Action.do的模式,都可通過該Action進行處理,而method屬性使用了一個表示式{1},該表示式的值就是name屬性中第一個*的值,例如,使用者請求的URL為LoginAction.do,則呼叫com.demo.LoginAction類的Login方法來處理,如果請示的URL為RegistryAction.do的話,則呼叫com.demo.LoginAction的Registry方法進行處理。
以下配置在class屬性中使用萬用字元:
<package name=”demo” extends=”struts-default”>
<action name=”*Action” class=”com.demo.{1}Action”>
<result name=”input”>/input.jsp</result>
<result name=”error”>/error.jsp</result>
<result name=”success”>/success.jsp</result>
</action>
</package>
此配置中沒有指定method屬性,所以請示由預設的execute方式來執行,但class中使用了萬用字元,它的含義與上面一樣,例如,當用戶請求的為LoginAction.do時,其中*的值為Login,該值傳入class屬性,即該Action的處理類為com.demo.LoginAction;而如果請求為RegistryAction.do時,則該Action的處理類將變為com.demo.RegistryAction。
Struts2允許在class屬性和method屬性中同時使用表示式,示例如下:
<action name=”*_*” class=”com.demo.{1} method=”{2}” />
不難看出,只要滿足*_*模式的Action都會被其處理,例如有Order_Booking.do請求到來,由於第一個*的值為Order,第二個*的值為Booking,那麼意味著將會呼叫com.demo.Order處理類中的Booking方法來處理使用者請求。
Struts2除了允許在name、class、method中使用表示式外,在<result/>元素中也可以使用表示式,如下:
<action name=”*Action” class=”com.demo.{1}Action method=”{1}” >
<result name=”success”>/{1}.jsp</result>
</action>
當請求為LoginAction.do時,將呼叫com.demo.LoginAction處理類中的Login方法處理使用者的請求,當返回為success時,顯示/Login.jsp頁面。
注意:在使用萬用字元後,除非請求的URL與Action的name屬性絕對相同,否則將按Action在struts.xml中定義的先後順序來決定由哪個Action來處理使用者請求。
對於一些只是簡單的轉發操作,如超級連結等的請求,可以定義name為*的Action來處理,此外,Struts2框架允許在struts.xml中使用<default-action-ref/>元素定義一個預設Action來處理使用者請求:
<package name=”demo” extends=”struts-default” namespace=”/”>
<action name=”defaultAction” class=”com.demo.DefaultAction”>
<result>/default.jsp</action>
</action>
<default-action-ref name=”defaultAction” />
</package>
<default-action-ref/>的name屬性為struts.xml中一個已經定義好的Action。