ActionForm的Date处理问题参考:http://jgj228.blog.163.com/blog/static/4520113220084279454245/??基于St
ActionForm的Date处理问题
参考:http://jgj228.blog.163.com/blog/static/4520113220084279454245/
?
?
基于Struts做应用程序开发的时候,对日期数据的处理,这个是最常见的,由于Struts默认是不支持自动将网页POST的数据自动转化成Date型数据,所以,很多程序员就直接在ActionForm当中直接使用String,然后在Action当中再进行字符串跟日期数据的处理。
那假如在ActionForm当中是使用Date类型呢?会出现什么问题?能用什么样的解决办法?我们先看一下在ActionForm当中会出现的问题先。
首先,我们先创建一个新的Struts工程,创建一个新的ActionForm,取名叫UserForm,UserForm的实现代码如下:

?程序代码package zizz.struts;
import java.util.Date;
import org.apache.struts.action.ActionForm;
/**
* UserForm对应着提交页面的网页表单信息
* @author chen yuzhe
*
*/
public?
class?UserForm extends ActionForm{
????/**
???? * serialVersionUID
???? */
????
private?
static?final?
long?serialVersionUID?=?-742922986494711669L;
????
private?
int?id;
????
????
private?String name;
????
????
private?
int?age;
????
????
private?String loginId;
????
????
private?Date birthday;
????
public?
int?getAge()?{
????????
return?age;
????}
????
public?
void?setAge(
int?age)?{
????????
this.age?=?age;
????}
????
public?Date getBirthday()?{
????????
return?birthday;
????}
????
public?
void?setBirthday(Date birthday)?{
????????
this.birthday?=?birthday;
????}
????
public?
int?getId()?{
????????
return?id;
????}
????
public?
void?setId(
int?id)?{
????????
this.id?=?id;
????}
????
public?String getLoginId()?{
????????
return?loginId;
????}
????
public?
void?setLoginId(String loginId)?{
????????
this.loginId?=?loginId;
????}
????
public?String getName()?{
????????
return?name;
????}
????
public?
void?setName(String name)?{
????????
this.name?=?name;
????}
????
}
第二,编写user_form.jsp的表单页面,user_form.jsp的代码如下:

?程序代码
<%@ page contentType="text/html; charset=GBK"%
><%@ taglib uri="http://struts.apache.org/tags-html"?prefix="html"?%
><!DOCTYPE html PUBLIC?"-//W3C//DTD HTML 4.01 Transitional//EN"?"http://www.w3.org/TR/html4/loose.dtd"
><html
><head
><meta http-equiv="Content-Type"?content="text/html; charset=GBK"
><title
>用户信息表单
</title
></head
><body
>????
<div
><strong
>创建新用户
</strong
></div
>????
<html:form action="/userSave"
>????????
<table width="50%"?border="1"
>????????????
<tr
>????????????????
<td
>编号
</td
>????????????????
<td
><html:text property="id"
/></td
>????????????
</tr
>????????????
????????????
<tr
>????????????????
<td
>姓名
</td
>????????????????
<td
><html:text property="name"?
/></td
>????????????
</tr
>????????????
????????????
<tr
>????????????????
<td
>登录号
</td
>????????????????
<td
><html:text property="loginId"?
/></td
>????????????
</tr
>????
????????????
<tr
>????????????????
<td
>年龄
</td
>????????????????
<td
><html:text property="age"?
/></td
>????????????
</tr
>????????????????????
????????????
<tr
>????????????????
<td
>生日
</td
>????????????????
<td
><html:text property="birthday"?
/></td
>????????????
</tr
>????????????
????????
</table
>????????
<hr
>????????
<html:submit
></html:submit
>????????
<html:reset
></html:reset
>????
</html:form
></body
></html
>
第三,配置struts-config.xml文件,struts-config.xml文件配置如下:

?程序代码
<?xml version="1.0"?encoding="UTF-8"
?><!DOCTYPE struts-config PUBLIC?"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN""http://struts.apache.org/dtds/struts-config_1_2.dtd"
><struts-config
>??
<data-sources?
/>??
<form-beans
>??????
<form-bean name="userForm"?type="zizz.struts.UserForm"
></form-bean
>??
</form-beans
>??
<global-exceptions?
/>??
<global-forwards?
/>??
<action-mappings
>??????
<action path="/userSave"?name="userForm"?validate="false"?scope="request"?type="zizz.struts.UserSaveAction"
></action
>??
</action-mappings
>??
<message-resources parameter="zizz.struts.ApplicationResources"?
/></struts-config
>
第四步,发布该应用程序,浏览,并提交页面,如下图所示:

提交将会报以下的错误信息:

?程序代码
exception?
javax.servlet.ServletException: BeanUtils.populate
????org.apache.struts.util.RequestUtils.populate(RequestUtils.java:495)
????org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:805)
????org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203)
????org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
????org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
????javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
????javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause?
java.lang.IllegalArgumentException: Cannot invoke zizz.struts.UserForm.setBirthday - 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:493)
????org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:805)
????org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203)
????org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
????org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
????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.
会报这个问题其实就是Struts没有提供相应的转换工具,我们都知道,网页POST过来的所有数据都是String类型,那为什么在ActionForm当中定义int型没有问题呢,原因就是Struts内部有一个类型转换器,能够自动地将String类型转换成为int,float,double,Integer,Float,Double等类型。那继承Struts内部有这些转换器,那我们是否可以对其进行扩展?答案是可以的,Struts的Converter框架很好地支持了这一点。
第五步,创建一个日期转换器类DateConverter.java,该类代码如下:

?程序代码package zizz.struts;
import java.text.SimpleDateFormat;
import org.apache.commons.beanutils.Converter;
import java.util.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.text.ParseException;
/**
*?
* 日期转换对象,使用该转换器,在BaseForm当中做一下注册,系统自动地帮助字符的日期表示转换为java.util.Date对象.
* @author zizz.
* Create Time:2006-9-11 19:11:47.
*/
public?
class?DateConverter implements Converter?{
????/**
???? * 日期格式化对象.
???? */
????
private?
static?SimpleDateFormat df?=?
new?SimpleDateFormat();
????
????/**
???? * 模式集合.
???? */
????
private?
static?Set<String>?patterns?=?
new?HashSet<String>();
????//注册一下日期的转换格式
????
static{
????????DateConverter.patterns.add("yyyy-MM-dd");
????????DateConverter.patterns.add("yyyy-MM-dd HH:mm");
????????DateConverter.patterns.add("yyyy-MM-dd HH:mm:ss");
????????DateConverter.patterns.add("yyyy/MM/dd HH:mm:ss");
????}
????
????/**
???? * 日期转换器.
???? * @param type Class
???? * @param value Object
???? * return Date Object.
???? */
????
public?Object convert(Class type,Object value){
????????
if(value?==?null){
????????????
return?null;
????????}
else?
if(value instanceof String){
????????????Object dateObj?=?null;
????????????Iterator it?=?patterns.iterator();
????????????
while(it.hasNext()){
????????????????
try{
????????????????????String pattern?=?(String)it.next();
????????????????????df.applyPattern(pattern);
????????????????????dateObj?=?df.parse((String)value);
????????????????????
break;
????????????????}
catch(ParseException ex){
????????????????????//do iterator continue
????????????????}
????????????}
????????????
return?dateObj;
????????}
else{
????????????
return?null;
????????}
????}
}
第六步,注册日期转换器
自定义的日期转换工作必须先做注册才能使用,注册我们可以将其放在ActionForm当中。
使用以下代码进行注册:
ConvertUtils.register(new DateConverter(), Date.class);
进行注册
修改完的UserForm.java如下:

?程序代码package zizz.struts;
import java.util.Date;
import org.apache.struts.action.ActionForm;
import org.apache.commons.beanutils.ConvertUtils;
/**
* UserForm对应着提交页面的网页表单信息
* @author chen yuzhe
*
*/
public?
class?UserForm extends ActionForm{
????
????
static{
????????ConvertUtils.
register(
new?DateConverter(),?Date.
class);
????}
????/**
???? * serialVersionUID
???? */
????
private?
static?final?
long?serialVersionUID?=?-742922986494711669L