Exception: BeanUtils.populate, argument type mismatch

本文探讨了在Struts框架中使用非字符串类型的日期属性时出现的BeanUtils.populate异常问题。详细分析了问题产生的原因,并提供了两种解决方案:一是自定义ActionServlet进行类型转换;二是将日期属性类型改为字符串,在Action中进行转换。

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基类中注册类型转换类。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值