【文章标题】Struts 1 中DispatcherAction类原理浅析
【文章作者】曾健生
【作者邮箱】zengjiansheng1@126.com
【作者QQ】190678908
【作者声明】本人水平有限,失误之处,敬请各位指出。
*******************************************************************************
Struts 1 中有个类DispatcherAction能够在同一个 Action 类中完成一组相关的业务操作,以达到减少重复编程,使程序更加便于维护。
DispatcherAction类的使用方法:
1. 创建一个扩展 DispatchAction 类的子类,不必覆盖 excute() 方法,而是创建一些实现业务逻辑的方法,这些业务逻辑方法都应该和 excute() 方法具有相同的方法签名,即它们的参数和返回类型都应该相同。
2. 在配置DispatcherAction类时,需要把 parameter 属性的值设置为”method”,当然了,method的名称不是固定的,只需要把保持配置文件中和在传递参数一致即可。
3. 当用户请求访问 DispatchAction 时,必须提供 method 请求参数.例如: http://localhost:8080/test/test?method=add
如果读者了解java中的反射技术就不难明白,这个DispatchAction类的实现就是使用了反射技术后的Action类。
在java中“万物皆对象”,反射技术把这个理念贯彻得淋漓尽致,可以把“反射”解释为把java类的各个部分(构造函数,属性,方法,甚至包括注释等)都看成是一个对象,当然了,方法也是一个对象。
所有的类都有一个class对象,通过class对象的getMethod方法可获取类中制定的方法对象,getMethod方法的声明如下:
public Method getMethod(String name,
Class... parameterTypes)
参数:
String name:方法的名称。
Class... parameterTypes:是个可变参数列表,值为方法的各个参数的class。
返回值:
为所需要的方法对象
Method对象有关invoke方法,可实现函数的执行,声明如下:
public Object invoke(Object obj,
Object... args)
Object obj:需要执行函数所在类的实例,因为method对象不属于任何类,所以必须指定所依赖的类的实例。
Object... args:函数需要的参数。
下面就举一个小例子,用Action类加上“反射技术”模拟实现DispatcherAction类的功能。
首先,一个usermanage.jsp文件中有四个超链接如下图1所示:
图1
代码如下:
<html:link action="usermanage?met=addUser">AddUser</html:link><br>
<html:link action="usermanage?met=deleteUser">DeleteUser</html:link><br>
<html:link action="usermanage?met=updateUser">UpdateUser</html:link><br>
<html:link action="usermanage?met=getUser">QueryUser</html:link><br>
每个超链接中的参数“met=xxx”对应同一个action相关的业务方法,“xxx”为对应的方法名
在struts-config.xml中配置如图2所示:
注意黑色框部分,需要比一般的action多添加一个parament属性,作用是指定参数的名称。有的朋友可能会问上述超链接“usermanage?met=getUser”中的met是固定的吗?其实就是在这里配置需要的参数名。
好,现在准备工作已经完成,下一步就是重点了,利用反射技术实现DispatcherAction的功能。
public ActionForward execute(ActionMapping arg0, ActionForm arg1,
HttpServletRequest arg2, HttpServletResponse arg3) throws Exception {
String patameter = arg0.getParameter(); //获取配置的参数名称,即met
//获取参数的值,即met=xxx中的xxx
String methodName = arg2.getParameter(patameter);
//用反射技术获取方法对象
Method method = this.getClass().getMethod(methodName, ActionMapping.class, ActionForm.class,
HttpServletRequest.class, HttpServletResponse.class);
//执行相对应的方法
return (ActionForward) method.invoke(this, arg0, arg1, arg2, arg3);
}
假设点击的超级链接为“AddUser”,即点击的超链接为
<html:link action="usermanage?met=addUser">AddUser</html:link>
应该是调用对应的addUser方法,写下如下的测试代码:
public ActionForward addUser(ActionMapping arg0, ActionForm arg1,
HttpServletRequest arg2, HttpServletResponse arg3) throws Exception {
// TODO Auto-generated method stub
System.out.println("addUser...");
return null;
}
在Console窗口中显示如图3的输出信息:
图3
(*^__^*) 嘻嘻……,果然调用了addUser()方法,模仿成功!!