AppFuse表现层(Struts实现)

AppFuse表现层(Struts实现)

在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);
    }

你可能感兴趣的:(AppFuse表现层(Struts实现))