read AppFuse 9-BaseAction类分析

read AppFuse BaseAction类分析

      功能:通过请求的参数来决定该执行哪一个方法,而不像一般的Action,从Execute方法执行。

BaseActionAppFuse中作为所有Action的父类。使用LookupDispatchAction,在一个窗体中包括两个以上同名的按钮时,由Struts来决定具体执行那个按钮操作,减少了Action类,增加了请求处理的灵活性。继承了LookupDispatchAction后,需要复写 getKeyMethodMap()方法。

 

 

 

 

 

Ø StrutsLookupDispatchAction类说明

    LookupDispatchActionDispatchAction的子类。它们都允许同一个Action根据请求URL

中的不同参数执行不同操作(即调用不同的函数)。DispatchAction的子类是根据用户请

URL中的参数,严格匹配DispatchAction子类中的方法名称来实现的。而

LookupDispatchAction的实现则是资源配置文件的Map结构中的键-值,和用户请求URL

中的参数匹配,反向查询资源文件绑定,并将查询得到的键值和Action类中的具体方法匹

配,选择具体的方法执行。

继承LookupDispatchAction的子类,复写getKeyMethodMap()方法,该方法返回一个包含一组

/值对的java.util.Map。而这个Map的键应该和资源属性文件中的键匹配,与Map中的每个键相关的

值,应该和LookupDispatchAction子类中的方法名称严格匹配。

 

 

 

 

 

例子:如(1)editUser.html?username=tomcat&from=list&method=edit

           (2) editUser.html?username=tomcat&from=list&method=search

     Struts可以根据请求URL中的method参数,使得同

一个org.dudu.webapp.action.UserAction执行不同的操作。

 

 

 

 

 

Ø BaseAction

public class BaseAction extends LookupDispatchAction {

    //根据请求参数和属性文件中的属性比较,填充Map映射结构

    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 {

    //具体的操作方法search

    public ActionForward search(ActionMapping mapping, ActionForm form,

                                HttpServletRequest request,

                                HttpServletResponse response)

         throws Exception {

        //具体的操作方法cancel

    public ActionForward cancel(ActionMapping mapping, ActionForm form,

                                HttpServletRequest request,

                                HttpServletResponse response)

    throws Exception { }

    //具体的操作方法delete

    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,而指定的LocaleCHINESE,那么最适合匹配的类名称为TestBundle_zh_CN.class,而最佳匹配属性文件名称为TestBundle_zh_CN.properties。按照Java Doc和相关文档的要求,如果该类或属性文件没有找到,系统会查找近似匹配(主文件名依次为TestBundle_zhTestBundle的类或属性文件)。该类提供的getKeys()方法用于获得所有成员的键名,并提供handleGetObject方法获得指定键的对应元素。

 

 

 

 

 

      问题:看这一部分时,我遇到了一个问题,如果那位兄弟知道结果,烦请相告,不胜感激。

AppFuse查看用户列表页面,单击用户信息表格中的用户名,在浏览器下的状态栏中显示

URLeditUser.html?username=tomcat&from=list
如果在AppFuse中的BaseAction处理,按照read AppFuse BaseAction类分析中谈到,
URL
应该是editUser.html?username=tomcat&from=list &method=edit,程序才会按照LookupMethods.properties的配置,跳到查看具体用户信息的页面,但现在URL中并没有method=edit这一个匹配条件,那程序是根据什么条件跳动
用户信息的页面呢?

★ 感谢网友zbird的帮助,问题解决,调试结果如下:

1BaseAction

    public ActionForward execute(ActionMapping mapping, ActionForm form,

                                 HttpServletRequest request,

                                 HttpServletResponse response)

            throws Exception {

        log.debug("BaseAction: entering BaseAction... ... ");

        if (isCancelled(request)) {

            ActionForward af = cancelled(mapping, form, request, response);

            if (af != null) {

                return af;

            }

        }

        MessageResources resources = getResources(request);

        // Identify the localized message for the cancel button

        String edit = resources.getMessage(Locale.ENGLISH, "button.edit").toLowerCase();

        String save = resources.getMessage(Locale.ENGLISH, "button.save").toLowerCase();

        String search = resources.getMessage(Locale.ENGLISH, "button.search").toLowerCase();

        String view = resources.getMessage(Locale.ENGLISH, "button.view").toLowerCase();

        String[] rules = {edit, save, search, view};

        // Identify the request parameter containing the method name

        //判断请求参数中是否包含method参数名称

        String parameter = mapping.getParameter();

        // don't set keyName unless it's defined on the action-mapping

        // no keyName -> unspecified will be called

        String keyName = null;

        if (parameter != null) {

            keyName = request.getParameter(parameter);

        }

 

 

 

        log.debug("BaseAction: keyName:" + keyName);       

        String path="";

         

        if ((keyName == null) || (keyName.length() == 0)) {

            for (int i = 0; i < rules.length; i++) {          

                // apply the rules for automatically appending the method name

                //keyName == null,即请求参数中不包含method参数名称时

              //此时的path is:/editUser.html,而rules[0]="edit", 

              //通过indexOf操作,匹配并执行以下代码

//即当请求UserAction时,如果请求参数中没有method属性名,

//就默认执行edit方法,

               //以这种方式实现默认操作,无言,有些晦涩,浪费了很多时间去阅读

                if (request.getServletPath().indexOf(rules[i]) > -1) {

                  path = request.getServletPath();

                log.debug("BaseAction: path is:" + path);

                log.debug("BaseAction: rules[i] " + rules[i]);

                log.debug("BaseAction: rules[i] index i= " + i);                 

                 return dispatchMethod(mapping, form, request, response, rules[i]);

                }

            }

        if (log.isDebugEnabled()) {

            log.debug("BaseAction: exit for" + keyName);

        }

            return this.unspecified(mapping, form, request, response);

        }

        // Identify the string to lookup

//如果请求参数中包含method参数名称时,取得Map值,执行对应的操作,如add

//操作。

        String methodName =

                getMethodName(mapping, form, request, response, parameter);

    if (log.isDebugEnabled()) {

        log.debug("BaseAction: parameter " + parameter);

    }

        return dispatchMethod(mapping, form, request, response, methodName);

    }

2)完整的调试结果:

[dudu] DEBUG [http8080-Processor25] UserAction.search(275) | Entering 'search' method

[dudu] DEBUG [http8080-Processor25] BaseAction.execute(172) | BaseAction: entering BaseAction... ...

[dudu] DEBUG [http8080-Processor25] BaseAction.execute(200) | BaseAction: keyName:null

[dudu] DEBUG [http8080-Processor25] BaseAction.execute(208) | BaseAction: path is:/editUser.html

[dudu] DEBUG [http8080-Processor25] BaseAction.execute(209) | BaseAction: rules[i] edit

[dudu] DEBUG [http8080-Processor25] BaseAction.execute(210) | BaseAction: rules[i] index i= 0

[dudu] DEBUG [http8080-Processor25] UserAction.edit(124) | Entering 'edit' method

[dudu] DEBUG [http8080-Processor25] UserAction.checkForCookieLogin(332) | checking for cookieLogin...

[dudu] DEBUG [http8080-Processor23] BaseAction.execute(172) | BaseAction: entering BaseAction... ...

[dudu] DEBUG [http8080-Processor23] BaseAction.execute(200) | BaseAction: keyName:Search

[dudu] DEBUG [http8080-Processor23] BaseAction.getLookupMapName(389) | BaseActin: getLookupMapName( keyName = Search )

[dudu] DEBUG [http8080-Processor23] BaseAction.getLookupMapName(399) | BaseActin: keyName not found in resource bundle with locale zh_CN

[dudu] DEBUG [http8080-Processor23] BaseAction.execute(224) | BaseAction: paramter method

[dudu] DEBUG [http8080-Processor23] UserAction.search(275) | Entering 'search'ethod

[dudu] DEBUG [http8080-Processor23] BaseAction.execute(172) | BaseAction: enterng BaseAction... ...

[dudu] DEBUG [http8080-Processor23] BaseAction.execute(200) | BaseAction: keyNae:Add

[dudu] DEBUG [http8080-Processor23] BaseAction.getLookupMapName(389) | BaseActin: getLookupMapName( keyName = Add )

[dudu] DEBUG [http8080-Processor23] BaseAction.getLookupMapName(399) | BaseActin: keyName not found in resource bundle with locale zh_CN

[dudu] DEBUG [http8080-Processor23] BaseAction.execute(224) | BaseAction: paramter method

[dudu] DEBUG [http8080-Processor23] UserAction.add(63) | Entering 'add' method[dudu] DEBUG [http8080-Processor23] UserAction.checkForCookieLogin(332) | check

ng for cookieLogin...

调试时我还发现UserAction中的checkForCookieLogin运行时非常的耗费时间,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值