Preface
在浏览本文之前,请确定你是在以下相似environment和condition下遇到相似问题。
Environment:
OS: Windows XP
Language: Java 1.5
Framework: Struts 1.3
IDE: MyEclipse 6.0
Condition:
在jsp page上有Date的input,而在actionForm中相应地define了Date type的property来get jsp page上的input。
Introduction
本文主要讲述struts actionForm中define非String data type可能会遇到的Exception: BeanUtils.populate, argument type mismatch。
Section 1 - Problem
在jsp页面上收到的都是String type input,
如果在actionForm中define Integer type的property,
actionForm能自动对从jsp page中来的String type input进行type conversion,
然后通过set method将Integer type的value赋给define好的Integer type property。
可是,
如果在actionForm中define java.util.Date type的property的话,
当actionForm从jsp page get input的时候就会遇到如下Exception:
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.servlet.ServletException: BeanUtils.populate org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:286) org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913) org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
javax.servlet.ServletException: BeanUtils.populate org.apache.struts.util.RequestUtils.populate(RequestUtils.java:469) org.apache.struts.chain.commands.servlet.PopulateActionForm.populate(PopulateActionForm.java:50) org.apache.struts.chain.commands.AbstractPopulateActionForm.execute(AbstractPopulateActionForm.java:60) org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51) org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190) org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304) org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190) org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283) org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913) org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
java.lang.IllegalArgumentException: Cannot invoke fms.struts.form.TestDateTimeForm.setLastUpdateDateFrom - argument type mismatch org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:1778) org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:1759) org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1648) org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:1677) org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:1022) org.apache.commons.beanutils.BeanUtilsBean.populate(BeanUtilsBean.java:811) org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:298) org.apache.struts.util.RequestUtils.populate(RequestUtils.java:467) org.apache.struts.chain.commands.servlet.PopulateActionForm.populate(PopulateActionForm.java:50) org.apache.struts.chain.commands.AbstractPopulateActionForm.execute(AbstractPopulateActionForm.java:60) org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51) org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190) org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304) org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190) org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283) org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913) org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462) javax.servlet.http.HttpServlet.service(HttpServlet.java:710) javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
note The full stack trace of the root cause is available in the Apache Tomcat/6.0.13 logs.
Apache Tomcat/6.0.13
Section 2 - Reason
以下的link提出了同一个问题,不论对错可以看看先
http://topic.csdn.net/t/20050114/11/3725181.html
这里我再总结一下实际的reason,经本人测试,actionForm中的property不一定要全部非为String type不可,至少可以为Integer, Float, Boolean等。现在发现只是Date比较特别,Struts的ActionServlet在接受到page的request后,会call RequestUtils.populate method对form进行填值,而RequestUtils.populate method又call BeanUtils.populate method,该BeanUtils.populate method进行填值时对不同data type会进行conversion,但default的ActionServlet并没有register相应的String to Date conversion method,结果使得在acitonForm中将property define为Date type就会遇到这个exception。
Section 3 - Solution
1. 实现自定义的ActionServlet方法并在里面注册转换函数。
2. Form中的日期类型使用String类型,把转换动作放在Action中处理(即在Action中对Form->POJO转换时处理),可以在Action基类中注册类型转换类。
本文探讨了在Struts框架中使用非字符串类型的日期属性时出现的BeanUtils.populate异常问题。详细分析了问题产生的原因,并提供了两种解决方案:一是自定义ActionServlet进行类型转换;二是将日期属性类型改为字符串,在Action中进行转换。
203

被折叠的 条评论
为什么被折叠?



