[转]基于Converter解决Struts无法处理日期类型的问题

原文地址:基于Converter解决Struts无法处理日期类型的问题

基于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;

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;

}

}

第七步,测试:
有问题的可以跟我联系,yuzhechen@163.com

Comments are closed.