read AppFuse BaseAction类分析
★ 功能:通过请求的参数来决定该执行哪一个方法,而不像一般的Action,从Execute方法执行。
BaseAction在AppFuse中作为所有Action的父类。使用LookupDispatchAction,在一个窗体中包括两个以上同名的按钮时,由Struts来决定具体执行那个按钮操作,减少了Action类,增加了请求处理的灵活性。基础LookupDispatchAction后,需要复写 getKeyMethodMap()方法。
Ø BaseAction类
public class extends LookupDispatchAction {
//根据请求参数和属性文件中的属性比较,取得具体的执行函数
public Map getKeyMethodMap() {
Map map = new HashMap();
String pkg = this.getClass().getPackage().getName();
//通过ResourceBundle.getBundle在运行时动态加载属性文件
// org.dudu.webapp.action包中的LookupMethods.properties
//属性文件中对应的具体方法,如add方法在BaseAction的子类中定义
ResourceBundle methods =
ResourceBundle.getBundle(pkg + ".LookupMethods");
Enumeration keys = methods.getKeys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
map.put(key, methods.getString(key));
}
return map;
}
Ø具体实现的子类
public final class UserAction extends BaseAction {
public ActionForward search(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
public ActionForward cancel(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {… …}
public ActionForward delete(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {… …}
Ø Struts-config.xml中的配置1
<forward name="viewUsers" path="/editUser.html?method=Search"/>
Ø Struts-config.xml中的配置2
<action
path="/editUser"
type="org.dudu.webapp.action.UserAction"
name="userForm"
scope="request"
input="list"
roles="admin"
parameter="method"
unknown="false"
validate="false"
>
Ø 说明: 用户提出viewUsers请求时,请求参数中的method=Search参数被UserAction的父类
BaseAction处理,BaseAction的父类LookupDispatchAction会根据该参数method=Search,在属性文件
中文件找到对应的key,然后根据key与从getKeyMethodMap()得知要执行的方法search。
public ActionForward search(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
if (log.isDebugEnabled()) {
log.debug("Entering 'search' method");
}
UserForm userForm = (UserForm) form;
// Exceptions are caught by ActionExceptionHandler
UserManager mgr = (UserManager) getBean("userManager");
User user = (User) convert(userForm);
List users = mgr.getUsers(user);
request.setAttribute(Constants.USER_LIST, users);
// return a forward to the user list definition
return mapping.findForward("list");
}
注:LookupMethods.properties属性文件中的内容
button.add=add
button.cancel=cancel
button.copy=copy
button.edit=edit
button.delete=delete
button.save=save
button.search=search
注解[引用]:
ResourceBundle:该类是一个抽象类,需要通过静态方法ResourceBundle.getBundle()指定具体实现类或属性文件的基本名称。基本名称会协同指定的或默认的Locale类,决定具体调用的类或属性文件的唯一名称。例如:指定基本类或属性文件名称为TestBundle,而指定的Locale是CHINESE,那么最适合匹配的类名称为TestBundle_zh_CN.class,而最佳匹配属性文件名称为TestBundle_zh_CN.properties。按照Java Doc和相关文档的要求,如果该类或属性文件没有找到,系统会查找近似匹配(主文件名依次为TestBundle_zh和TestBundle的类或属性文件)。该类提供的getKeys()方法用于获得所有成员的键名,并提供handleGetObject方法获得指定键的对应元素。
★ 问题:看这一部分时,我遇到了一个问题,如果那位兄弟知道结果,烦请相告,不胜感激。
在appfuse的查看用户列表功能中,请求URL
是editUser.html?username=tomcat&from=list。
请求中并没有method这一个属性,但请求后连接竟然能自动找到UserActiong类中的edit方法,并执行,深感神奇。