1. 程式人生 > >Struts2——Action動態方法呼叫

Struts2——Action動態方法呼叫

     對於同一個表單,當用戶通過不同的按鈕提交同一個表單時,系統需要使用Action的不同方法來處理使用者請求,這時Action便需要包含多個控制處理邏輯,即一個action中包含多個方法。例如:login介面有“登入”和“註冊”兩個按鈕,分別觸發UserAction中的login和regist方法。

MVC模式:

     經典MVC模式中,事件由控制器(controller)處理,控制器根據事件型別改變檢視(view),簡言之,每個模型對應一系列的檢視列表,不同事件通過控制器觸發,獲取模型(model)數值,返回不同的檢視去呈現。

struts2——MVC模式實踐者:

     Action充當控制器(Controller),瀏覽器中URL地址輸入指定action名稱,觸發struts核心控制器StrutsPrepareAndExecuteFilter例項化出指定action物件,呼叫action中指定方法,通過方法返回值,讀struts.xml配置檔案返回指定jsp頁面(view)。

DMI——Action動態方法呼叫:

         初學時,action中方法總是比較單一的;例如上述登入和註冊的例子,一般會建立兩個action類,loginAction 和registeAction,分別寫好login和registe相關的業務邏輯;在struts配置檔案中也配置兩個action: 

		<action name="regist" class="cn.itcast.shop.user.action.loginAction">
			<result name="msg">/WEB-INF/jsp/regist.jsp</result>
		</action>
		
		<action name="login" class="cn.itcast.shop.user.action.registeAction"> 
			<result name="login">/WEB-INF/jsp/login.jsp</result>	 
 			<result name="loginSuccess" type="redirectAction">index</result>		 
		</action>

        但實際應用中,action的建立通常按模組劃分的;如使用者模組便建立一個userAction,關於使用者的登入、註冊、查詢等等方法,均寫到userAction中,這邊對應本文開頭,“系統需要使用Action的不同方法來處理使用者請求,這時Action便需要包含多個控制處理邏輯”。這時便涉及到action動態方法呼叫。

        DMI(Dynamic Method Invocation)是指呼叫aciton並不直接等同於呼叫某個action的名字,而是通過”actionname ! methodname”的形式,呼叫指定到action中具體方法執行。

以登入註冊為例,DMI實施步驟如下:

  1. 設定struts.xml 檔案DMI常量啟動動態方法呼叫:

    <constant name="struts. enable. DynamicMethodInvocation" value="true"/>    

       2、配置好action result值跳轉頁面<不同方法的返回值均配置到一個action標籤中>

<!-- 使用者模組Action -->
		<action name="userLoginRegist" class="cn.itcast.shop.user.action.UserAction">
			<result name="regist">/WEB-INF/jsp/regist.jsp</result>
			<result name="login">/WEB-INF/jsp/login.jsp</result>
			<result name="registSuccess">/WEB-INF/jsp/login.jsp</result>
			<result name="loginSuccess">/WEB-INF/jsp/index.jsp</result>
		</action>

       3、JSP中通過【action名 !方法名】的形式呼叫指定action中指定方法

                <input type="submit" value="註冊" onclick="regist()" >
		<script>
			function regist()
			{
				<span style="color:#000000;">form.action="userLoginRegist!regist";</span>
				//login同理
			}
		</script>

         或者還經常用到在jsp中這樣去呼叫:

		<body>
			<a href<span style="color:#000000;">=</span><strong><span style="color:#000000;">"</span><span style="color:#000000;">basePath/user/userLoginRegist!regist"/></span></strong>
			<br>
			<a hre<span style="color:#000000;">f=</span><strong><span style="color:#000000;">"</span><span style="color:#000000;">basePath/user/userLoginRegist!login"/></span></strong>
		</body> 

除了動態方法呼叫,另外還有兩種方式可實現呼叫同一個action中不同方法:

二、配置method屬性

         通過指定method屬性值,呼叫action中指定方法返回該方法result

                <action name="regist" class="cn.itcast.shop.user.action.UserAction" method="regist">
			<result name="regist">/WEB-INF/jsp/regist.jsp</result>
			<result name="registSuccess">/WEB-INF/jsp/login.jsp</result>
		</action>  
		
		<action name="login" class="cn.itcast.shop.user.action.UserAction" method="login">
			<result name="login">/WEB-INF/jsp/login.jsp</result>
			<result name="loginSuccess">/WEB-INF/jsp/index.jsp</result>
		</action> 

         Jsp直接呼叫:

		function regist()
			{
				form.action="regist";
				//login同理
			}

         不難看出,通過配置method屬性實現方法呼叫,這種做法直接導致:JSP呼叫一個方法,便需要在配置檔案中配置一個action標籤;也就是說這種方式是以方法為單位進行配置,呼叫多少個方法,便需要配置多少個action,而指向的action類全是一個。不可避免的增加了不必要的重複配置,笨拙繁瑣。

三、萬用字元

使用萬用字元便可解決方法二的弊端。

  1. 在action標籤中使用*表示action名稱,用{N}來表示前面第幾個*號所匹配的方法。

    		<!-- 使用者模組Action -->
    		<action name="*Action" class="cn.itcast.shop.user.action.UserAction" method="{1}">
    			<result name="regist">/WEB-INF/jsp/regist.jsp</result>
    			<result name="login">/WEB-INF/jsp/login.jsp</result>
    			<result name="registSuccess">/WEB-INF/jsp/login.jsp</result>
    			<result name="loginSuccess">/WEB-INF/jsp/index.jsp</result>
    		</action>
    

    name="*Action "  代表這個action處理所有以Action結尾的請求

     method= "{1} "    根據前面請求methodname,呼叫action中的以methodname命名的方法 

    例如現在jsp呼叫login方法

    Form.action=”login”,通過讀取配置檔案,訪問loginAction中login方法。如果呼叫註冊,則Form.action=”regist”,通過讀取配置檔案,訪問registeAction中login方法。所以通過萬用字元,我們可以配置為User_ *Action method={1},則可以訪問User_*Action中的*方法,靈活可配。包括result 標籤中的name和頁面跳轉也可以使用萬用字元進行。形如:

     <package name="actions" extends="struts-default" namespace="/actions">
     <action name="Student*" class="com.bjsxt.struts2.action.StudentAction" method="{1}">
     <result>/Student{1}_success.jsp</result>
     </action>
    
     <action name="*_*" class="com.bjsxt.struts2.action.{1}Action" method="{2}">
     <result>/{1}_{2}_success.jsp</result>
     <!-- {0}_success.jsp -->
     </action>
     </package>
     {1}、{2}表示第一第二個佔位符
     *為萬用字元