在实际开发项目中,一个Action类中可能包含多个处理逻辑的action方法,如果为每一个action方法去配制一个<action>标签,可以想象,这将使得Struts2的配制文件变的何等的恐怖。庆幸的是Struts2为我们提供了一种解决方案,那就是支持DMI(Dynamic Method Invocation, 动态方法调用)。那什么是DMI呢?即是通过ActionName!methodName的方式来调用指定action类中的指定方法,而这个方法同默认的execute一样。同时Struts2的配制文件还支持通配符来解决上述问题。
下面就通过一个简单的例子来说明Struts2的这一特性:
1.在Eclipse中新建一个名为DMI的项目(关于在Eclipse中开发J2EE项目请参考我的上一篇文章),导入Struts2的架包,配制web.xml添加Struts2过滤器。
2.在WebContent下新建一个index.jsp页面如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>索引页</title>
</head>
<body>
访问<a href="<s:url action='method1Action'/>">
<s:url action="method1Action" forceAddSchemeHostAndPort="true" />
</a>执行结果如下:
<br />
<s:action name="method1Action" executeResult="true" />
<hr />
访问<a href="<s:url action='method2Action'/>">
<s:url action="method2Action" forceAddSchemeHostAndPort="true" />
</a>执行结果如下:
<br />
<s:action name="method2Action" executeResult="true" />
<hr />
访问<a href="<s:url action='method3Action!test'/>">
<s:url action="method3Action!test" forceAddSchemeHostAndPort="true" />
</a>执行结果如下:
<br />
<s:action name="method3Action!test" executeResult="true" />
</body>
</html>
其中的url标签用于生成URL地址。其中forceAddSchemeHostAndPort属性强制指定在URL中 加入 scheme 、 host 和 port。
而action标签用于引入一个action,属性executeResult指定是否将指定的action的执行结果显示出来。
在其中的调用method3Action!test的方法就是动态调用方法,在Struts2中可以通过设定struts.enable.DynamicMthodInVocation常量为false来禁止使用此功能,默认为true。
3.创建名为DMIAction的Action类:
package org.websoft.action;
public class DMIAction{
private String tip;
public String getTip() {
return tip;
}
public String method1() throws Exception {
tip = "调用了method1 Action";
return "success";
}
public String method2() throws Exception {
tip = "调用了method2 Action";
return "success";
}
public String method3() throws Exception {
tip = "调用了method3 Action";
return "success";
}
public String test() throws Exception {
tip = "调用了test Action";
return "success";
}
}
上面的Action类定义了4个action执行逻辑方法。而属性tip用于显示系统调用执行的是哪个逻辑方法。
4.在src下新建一个Struts2的配制文件struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
"http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
<package name="default" extends="struts-default">
<action name="*Action" class="org.websoft.action.DMIAction" method="{1}">
<result>dmi.jsp</result>
</action>
<!-- 不指定class属性则默认为ActionSupport类 -->
<action name="index">
<!-- 不指定result标签的name属性则默认为success -->
<result>index.jsp</result>
</action>
</package>
</struts>
观察上面的配制文件,使用了通配符 *; 在Struts2中允许在配制<action ../>元素时指定name属性使用模式字符串(即用*代表一个或多个任意字符),接下来就可以在class、method属性甚至于<result .../>子元素中使用{N}的形式代表前面第N个星号(*)所匹配的子串;其中的{0}表示全部的匹配字符串,故在这里使用{1}来代表匹配的字符串.
同时可以看出Struts2中设置的默认值,极大方便了用户的开发。
5.创建dmi.jsp文件如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>动态方法调用测试</title>
</head>
<body>
<s:property value="tip" />
</body>
</html>
其中使用了property标签用于获取当前action对象中的属性,在这里必须为tip属性提供一个get方法。其实根据反射原理,其中的重要的是方法名,属性名可以不为tip但这里的get方法名必须为getTip()。
最后启动Tomcat服务器,输入http://localhost:8080/DMI/index.action或http://localhost:8080/DMI得到的运行结果如下:
注意上面说的使用{N}的权利不仅仅只有method属性,如class和<result ../>都可以,下面自己动手来试一下吧,^_^!