您的位置:首页 > 移动开发

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

2015-01-22 17:17 351 查看
上一篇博客主要是讲解ActionServlet中的一个方法processActionForm,当我们在截取字符串,再根据字符串取得ActionMapping之后,我们就要用利用ActionMapping来创建ActionForm,并且把ActionForm放到request或session中管理。获得ActionForm之后,我们就要将ActionForm中的数据放到Mapping中,以便实例化Action。在Struts1中有一个方法是专门把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方法:



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

[java] view
plaincopyprint?

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和转换类型等操作的,具体实现:

[java] view
plaincopyprint?

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

}

}

}

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

[java] view
plaincopyprint?

if (!isMultipart) {

names = request.getParameterNames();

}

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

[java] view
plaincopyprint?

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值,之后通过

[java] view
plaincopyprint?

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

properties.put(stripped, parameterValue);

}

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

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

[java] view
plaincopyprint?

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的方法就实现完毕,实现了这个方法有什么用处呢?敬请等待下一篇博文!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐