随笔 - 37  文章 - 14  trackbacks - 0
<2007年6月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿

随笔分类

随笔档案

文章分类

相关链接

搜索

  •  

最新评论

阅读排行榜

评论排行榜

在AppFuse框架中,struts action 采用了继承DispatchAction的方法来实现一个Action里实现多种操作。
首先看看DispatchAction原理
DispatchAction在配置上于标准的Action稍有不同,就是要在Action配置中多一个parametr属性,这个属性将指导DispatchAction找到对应的方法,例如这样配置

    <action
      
path="/persons"

      type
="com.lms.webapp.action.PersonAction"
      name
="personForm"
      scope
="request"
      input
="mainMenu"
      parameter
="method"
      unknown
="false"
      validate
="false"    >
parameter的属性值是可以任意起的,只要你记得在传参数的时候统一就可以了。比如我写了一个类似这样的Action,它继承自DispatchAction类,包含了三个操作方法,有Add(),Update(),Delete()。当我想要调用这个Action的Update操作时,提交的URL应该类似这样的:
http://localhost:8080/myapp/persons.do?method=update
在AppFuse中的应用
在AppFuse中,有个继承DispatchAction的BaseAction类,每个Action都继承BaseAction,因此在执行Action的时候,都先执行BaseAction里的execute()方法达到指导要执行哪个操作。代码如下
    public ActionForward execute(ActionMapping mapping, ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response)
    
throws Exception {
        
        
if (isCancelled(request)) {
            
try {
                getMethod(
"cancel");
                
return dispatchMethod(mapping, form, request, response, "cancel");
            }
 catch (NoSuchMethodException n) {
                log.warn(
"No 'cancel' method found, returning null");
                
return cancelled(mapping, form, request, response);
            }

        }


        
// Check to see if methodName indicated by request parameter
        String actionMethod = getActionMethodWithMapping(request, mapping);
        
        
if (actionMethod != null{
            
return dispatchMethod(mapping, form, request, response, actionMethod);
        }
 else {
            String[] rules 
= {"edit""save""search""view"};
            
for (int i = 0; i < rules.length; i++{
                
// apply the rules for automatically appending the method name
                if (request.getServletPath().indexOf(rules[i]) > -1{
                    
return dispatchMethod(mapping, form, request, response, rules[i]);
                }

            }

        }

        
        
return super.execute(mapping, form, request, response);
    }
代码分析:
isCancelled(request)方法:if the current form's cancel button was pressed!进而执行cancel方法。
getActionMethodWithMapping方法来确定所要执行的操作。在getActionMethod方法里,首先是判断request里是否有method=methodName,如果有则返回methodName;如果没有则判断request里是否有包含method.methodName的parameter,有的话则返回截取"method."后面的methodName。
如果通过getActionMethodWithMapping方法取不到methodName,则判断servletPath里是否有包含edit....等字符,以决定执行什么操作。
如果以上都不能取到methodName,那么将执行 return super.execute(mapping, form, request, response);通过查看DispatchAction源码发现最终会执行
unspecified(),而在AppFuse里的每个Action都会重写这个方法。
    private String getActionMethodWithMapping(HttpServletRequest request, ActionMapping mapping) {
        
return getActionMethod(request, mapping.getParameter());
    }


    
/** 
     * Gets the method name based on the prepender passed to it.
     
*/

    
protected String getActionMethod(HttpServletRequest request, String prepend) {
        String name 
= null;
        
        
// for backwards compatibility, try with no prepend first
        name = request.getParameter(prepend);
        
if (name != null{
            
// trim any whitespace around - this might happen on buttons
            name = name.trim();
            
// lowercase first letter
            return name.replace(name.charAt(0), Character.toLowerCase(name.charAt(0)));
        }

        
        Enumeration e 
= request.getParameterNames();

        
while (e.hasMoreElements()) {
            String currentName 
= (String) e.nextElement();

            
if (currentName.startsWith(prepend + ".")) {
                
if (log.isDebugEnabled()) {
                    log.debug(
"calling method: " + currentName);
                }


                String[] parameterMethodNameAndArgs 
= StringUtils.split(currentName, ".");
                name 
= parameterMethodNameAndArgs[1];
                
break;
            }

        }

        
        
return name;
    }
综上,在AppFuse里可以通过以下几种方法来达到指定实现哪种操作:
1:在路径里包含edit、add、delete字段
:http://loaclhost:8080/myapp/editPerson.html
2:在request里包含method.methodName参数
如:
        <html:submit styleClass="button" property="method.save" onclick="bCancel=false">
            
<fmt:message key="button.save"/>
        
</html:submit>
3:执行cancel操作
        <html:cancel styleClass="button" onclick="bCancel=true">
            
<fmt:message key="button.cancel"/>
        
</html:cancel>
4:都不执行以上操作时,执行unspecified()方法
    public ActionForward unspecified(ActionMapping mapping, ActionForm form,
                                     HttpServletRequest request,
                                     HttpServletResponse response)
            throws Exception {
        return search(mapping, form, request, response);
    }
posted on 2007-06-20 16:39 扭曲的铅笔 阅读(643) 评论(0)  编辑  收藏 所属分类: AppFuse

只有注册用户登录后才能发表评论。


网站导航: