对于同一个表单,当用户通过不同的按钮提交同一个表单时,系统需要使用Action的不同方法来处理用户请求,这时Action便需要包含多个控制处理逻辑,即一个action中包含多个方法。例如:login界面有“登录”和“注册”两个按钮,分别触发UserAction中的login和regist方法。
<a name="t0" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a>MVC模式:
经典MVC模式中,事件由控制器(controller)处理,控制器根据事件类型改变视图(view),简言之,每个模型对应一系列的视图列表,不同事件通过控制器触发,获取模型(model)数值,返回不同的视图去呈现。
<a name="t1" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a>struts2——MVC模式实践者:
Action充当控制器(Controller),浏览器中URL地址输入指定action名称,触发struts核心控制器StrutsPrepareAndExecuteFilter实例化出指定action对象,调用action中指定方法,通过方法返回值,读struts.xml配置文件返回指定jsp页面(view)。
<a name="t2" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a>DMI——Action动态方法调用:
初学时,action中方法总是比较单一的;例如上述登录和注册的例子,一般会创建两个action类,loginAction 和registeAction,分别写好login和registe相关的业务逻辑;在struts配置文件中也配置两个action:
[html]
<embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_1" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
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实施步骤如下:
-
设置struts.xml 文件DMI常量启动动态方法调用:
<constant name="struts. enable. DynamicMethodInvocation" value="true"/>
2、配置好action result值跳转页面<不同方法的返回值均配置到一个action标签中>
[html]
<embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_2" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
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中指定方法
[html]
<embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_3" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
input
type
=
"submit"
value
=
"注册"
onclick
=
"regist()"
-
lt;script
function regist()
{
-
<
span
style
=
"color:#000000;"
form.action
=
"userLoginRegist!regist"
;
</
span
//login同理
}
-
lt;/script
或者还经常用到在jsp中这样去调用:
[html]
<embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_4" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
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中不同方法:
<a name="t3" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a>二、配置method属性
通过指定method属性值,调用action中指定方法返回该方法result
[html]
<embed id="ZeroClipboardMovie_5" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_5" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=5&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
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直接调用:
[html]
<embed id="ZeroClipboardMovie_6" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_6" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=6&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
function regist()
{
-
form.action
=
"regist"
;
//login同理
-
}
不难看出,通过配置method属性实现方法调用,这种做法直接导致:JSP调用一个方法,便需要在配置文件中配置一个action标签;也就是说这种方式是以方法为单位进行配置,调用多少个方法,便需要配置多少个action,而指向的action类全是一个。不可避免的增加了不必要的重复配置,笨拙繁琐。
<a name="t4" style="box-sizing: border-box; background: transparent; color: rgb(79, 161, 219); text-decoration: none; margin: 0px; padding: 0px; font-weight: 400; outline: 0px;"></a>三、通配符
使用通配符便可解决方法二的弊端。
-
在action标签中使用表示action名称,用{N}来表示前面第几个号所匹配的方法。
[html]
<embed id="ZeroClipboardMovie_7" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_7" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=7&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
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和页面跳转也可以使用通配符进行。形如:
[html]
<embed id="ZeroClipboardMovie_8" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="16" height="16" name="ZeroClipboardMovie_8" align="middle" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=8&width=16&height=16" wmode="transparent" style="box-sizing: border-box;">
-
<
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
-
</
action
</
package >
{1}、{2}表示第一第二个占位符
*为通配符