深入浅出学习Struts框架(十二)-把ActionForm的数据放到Mapping

上一篇博客主要是讲解ActionServlet中的一个方法processActionForm,当我们在截取字符串,再根据字符串取得ActionMapping之后,我们就要用利用ActionMapping来创建ActionForm,并且把ActionForm放到request或session中管理。获得ActionForm之后,我们就要将ActionForm中的数据放到Mapping中,以便实例化Action。在Struts中有一个方法是专门把ActionForm的数据放到Mapping的,这个方法就是processPopulate。今天我们就来详细来看看这个方法。

首先这个方法主要的功能是将表单数据放到Map中,并且将Map的值根据ActionForm类型转换好后设置到ActionForm中。

这个方法具体的流程是首先执行ActionForm中的reset方法进行重置,然后得到表单中所有输入域的name名称,再调用request.getParameterValues(),根据name名称得到相应的值,最后将表单中的数据全部放到一个map中,map的key为表单输入域的名称,map的value为表单输入域的值(字符串数组),接下来调用一个第三方组件BeanUtils,将Map中的值,根据ActionForm中的类型先转换好,再调用ActionForm中的setter方法设置到ActionForm上。

下面咱们来跟随源代码来看看这个方法的实现过程.首先还是和以前博客一样设置断点,进入process方法,找到processPopulate方法:

进入这个方法,看到这个方法的实现源代码:

protectedvoid processPopulate(HttpServletRequest request,

                                   HttpServletResponse response,

                                   ActionForm form,

                                   ActionMapping mapping)

        throws ServletException {

        if (form == null) {

            return;

        }
        // Populate the bean properties of this ActionForm instance

        if (log.isDebugEnabled()) {

            log.debug(" Populating bean properties from this request");

        }
        form.setServlet(this.servlet);

        form.reset(mapping, request);
        if (mapping.getMultipartClass() != null) {

            request.setAttribute(Globals.MULTIPART_KEY,

                                 mapping.getMultipartClass());

        }

        RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix(),

                              request);
        // Set the cancellation request attribute if appropriate

        if ((request.getParameter(Constants.CANCEL_PROPERTY) != null) ||

            (request.getParameter(Constants.CANCEL_PROPERTY_X) != null)) {       
            request.setAttribute(Globals.CANCEL_KEY, Boolean.TRUE);

        } 
}

其中,form.reset(mapping, request);这个方法就是讲form重置,作用是使ActionForm中的值恢复初始状态。

下面RequestUtils.populate(form, mapping.getPrefix(), mapping.getSuffix()这个方法就是要完成填充map和转换类型等操作的,具体实现:

publicstaticvoid populate(

            Object bean,

            String prefix,

            String suffix,

            HttpServletRequest request)

            throws ServletException {

        // Build a list of relevant request parameters from this request
        HashMap properties = new HashMap();
        // Iterator of parameter names
        Enumeration names = null;

        // Map for multipart parameters

        Map multipartParameters = null;

         String contentType = request.getContentType();

        String method = request.getMethod();

        boolean isMultipart = false;

         if (bean instanceof ActionForm) {

            ((ActionForm) bean).setMultipartRequestHandler(null);

        }

 	MultipartRequestHandler multipartHandler = null;

        if ((contentType != null)

                && (contentType.startsWith("multipart/form-data"))

                && (method.equalsIgnoreCase("POST"))) {

            // Get the ActionServletWrapper from the form bean

            ActionServletWrapper servlet;

            if (bean instanceof ActionForm) {

                servlet = ((ActionForm) bean).getServletWrapper();

            } else {

                thrownew ServletException(

                        "bean that's supposed to be "

                        + "populated from a multipart request is not of type "

                        + "\"org.apache.struts.action.ActionForm\", but type "

                        + "\""

                        + bean.getClass().getName()

                        + "\"");

            }

             // Obtain a MultipartRequestHandler

            multipartHandler = getMultipartHandler(request);

             if (multipartHandler != null) {

                isMultipart = true;

                // Set servlet and mapping info

                servlet.setServletFor(multipartHandler);

                multipartHandler.setMapping(

                        (ActionMapping) request.getAttribute(Globals.MAPPING_KEY));

                // Initialize multipart request class handler

                multipartHandler.handleRequest(request);

                //stop here if the maximum length has been exceeded

                Boolean maxLengthExceeded =

                        (Boolean) request.getAttribute(

                                MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED);

                if ((maxLengthExceeded != null) && (maxLengthExceeded.booleanValue())) {

                    ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);

                    return;

                }

                //retrieve form values and put into properties

                multipartParameters = getAllParametersForMultipartRequest(

                        request, multipartHandler);

                names = Collections.enumeration(multipartParameters.keySet());

            }

        }

        if (!isMultipart) {

            names = request.getParameterNames();

        }
        while (names.hasMoreElements()) {

            String name = (String) names.nextElement();

            String stripped = name;

            if (prefix != null) {

                if (!stripped.startsWith(prefix)) {

                    continue;

                }

                stripped = stripped.substring(prefix.length());

            }

            if (suffix != null) {

                if (!stripped.endsWith(suffix)) {

                    continue;

                }

                stripped = stripped.substring(0, stripped.length() - suffix.length());

            }

            Object parameterValue = null;

            if (isMultipart) {

                parameterValue = multipartParameters.get(name);

            } else {

                parameterValue = request.getParameterValues(name);

            }
            // Populate parameters, except "standard" struts attributes

            // such as 'org.apache.struts.action.CANCEL'

            if (!(stripped.startsWith("org.apache.struts."))) {

                properties.put(stripped, parameterValue);

            }

        }

        // Set the corresponding properties of our bean

        try {

            BeanUtils.populate(bean, properties);

        } catch(Exception e) {

            thrownew ServletException("BeanUtils.populate", e);

        } finally {

            if (multipartHandler != null) {

                // Set the multipart request handler for our ActionForm.

                // If the bean isn't an ActionForm, an exception would have been

                // thrown earlier, so it's safe to assume that our bean is

                // in fact an ActionForm.

                ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);

            }

        }
    }

这段实现的前半部分是关于上传的代码,因为咱们这个实例不和上传有关,所以直接忽略,直接到

if (!isMultipart) {

            names = request.getParameterNames();

        }

这段代码,这段代码主要是获得表单的所有名称,之后通过下面这段代码:

while (names.hasMoreElements()) {

            String name = (String) names.nextElement();

            String stripped = name;

            if (prefix != null) {

                if (!stripped.startsWith(prefix)) {

                    continue;

                }

                stripped = stripped.substring(prefix.length());

            }

            if (suffix != null) {

                if (!stripped.endsWith(suffix)) {

                    continue;

                }

                stripped = stripped.substring(0, stripped.length() - suffix.length());

            }

            Object parameterValue = null;

            if (isMultipart) {

                parameterValue = multipartParameters.get(name);

            } else {

                parameterValue = request.getParameterValues(name);

            }

             // Populate parameters, except "standard" struts attributes

            // such as 'org.apache.struts.action.CANCEL'

            if (!(stripped.startsWith("org.apache.struts."))) {

                properties.put(stripped, parameterValue);

            }

        }

遍历名称,并且通过parameterValue = request.getParameterValues(name);获得名称对应的value值,之后通过

if (!(stripped.startsWith("org.apache.struts."))) {

                properties.put(stripped, parameterValue);

            }

将名称作为key值,讲名称的value值作为value值添加到map中,到此为止,我们就讲表单数据添加到了map中。

随后,调用第三方的组件来实现类型转换:

try {

            BeanUtils.populate(bean, properties);

        } catch(Exception e) {

            thrownew ServletException("BeanUtils.populate", e);

        } finally {

            if (multipartHandler != null) {

                // Set the multipart request handler for our ActionForm.

                // If the bean isn't an ActionForm, an exception would have been

                // thrown earlier, so it's safe to assume that our bean is

                // in fact an ActionForm.

                ((ActionForm) bean).setMultipartRequestHandler(multipartHandler);

            }

        }

这个方法会遍历ActionForm的值的类型,并且讲Map中的值的类型改为和ActionForm对应的类型。

到这里processPopulate的方法就实现完毕,实现了这个方法有什么用处呢?敬请等待下一篇博文!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深入浅出STRUTS 2 Struts Ti却发现了二者在技术与开发人员这两个层面上的共同之处,不久之后,两个项目就在WebWork的技术基础上进行了合并2。 当我们说起WebWork的时候,我们实际上说的是两个项目——XWork和WebWork。XWork是一个通用的命令框架,它提供了很多核心的功能,例如actions,验证和拦截器,它可以完全独立于执行上下文运行,并提供了一个内部的依赖注入机制,用来做配置和工厂实现的管理。 而WebWork则是一个完全独立的上下文。它用Web应用中运行所需的上下文把XWork包装起来,并提供了可以简化Web开发的特定实现。 Struts2的目标很简单——使Web开发变得更加容易。为了达成这一目标,Struts2中提供了很多新特性,比如智能的默认设置、annotation的使用以及“惯例重于配置”原则的应用,而这一切都大大减少了XML配置。Struts2中的Action都是POJO,这一方面增强了Action本身的可测试性,另一方面也减小了框架内部的耦合度,而HTML表单中的输入项都被转换成了恰当的类型以供action使用。开发人员还可以通过拦截器(可以自定义拦截器或者使用Struts2提供的拦截器)来对请求进行预处理和后处理,这样一来,处理请求就变得更加模块化,从而进一步减小耦合度。模块化是一个通用的主题——可以通过插件机制来对框架进行扩展;开发人员可以使用自定义的实现来替换掉框架的关键类,从而获得框架本身所不具备的功能;可以用标签来渲染多种主题(包括自定义的主题);Action执行完毕以后,可以有多种结果类型——包括渲染JSP页面,Velocity和Freemarker模板,但并不仅限于这些。最后,依赖注入也成了Struts2王国中的一等公民,这项功能是通过Spring框架的插件和Plexus共同提供的,与PicoContainer的结合工作还正在进行中。 本书的目的,是为了帮助读者掌握Struts2框架,并能够对组成框架的功能部件和可用的配置项有深刻的理解。我在书中还将介绍一些可以提高生产力的方法——包括默认配置项和应当注意的实现特性,可用的多种配置选项和一些开发技术。本书还会就与第三方软件进行集成的话题展开讨论。 2 Don Brown, Struts Ti项目的领导,他在文章中详细介绍了Struts Ti的历史

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值