在示范中心项目中,我们把ActionForm中日期类型的字段指定为String类型,而在对应的JavaBean中指定为java.sql.Date类型。当用户提交表单的时候,在Action里使用BeanUtils.copyProperties()方法从ActionForm构造JavaBean对象(详见利用BeanUtils在对象间复制属性)。这个方法在大部分时候都很好,但有一个问题,就是当用户没有填写日期类型字段时(而该字段并非必填),validator不会提出警告,而在copyProperties()时会报类型转换异常,原因是这时ActionForm中的该字段的值是空字符串(""),负责字符串向Date转换的SqlDateConverter类调用Date.valueOf("")方法,显然""是无法转换为日期的,所以会抛出异常。

通过查看代码和资料,我发现这个问题的解决方法其实非常简单。只要把带缺省值参数的SqlDateConverter重新注册一下,覆盖原有的注册信息就可以了,这个注册语句一般是写在系统初试化的地方,对于Struts应用程序,当然做在PlugIn里最方便。代码如下:

package etc;

import javax.servlet.ServletException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.SqlDateConverter;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;

public class ConverterPlugIn implements PlugIn{

    public 
void  init(ActionServlet servlet, ModuleConfig config) throws ServletException {
        ConvertUtils.register(
new  SqlDateConverter( null ),java.sql.Date.class);
    }

    public 
void  destroy() {
        ConvertUtils.deregister();
    }
}

注意SqlDateConverter的构造方法是带有参数null的,这表示遇到不能解析的字符串就返回空值。而deregister()方法的作用是恢复ConvertUtils的缺省注册表。为了使这个PlugIn起作用,要在struts-config.xml里增加一句话:

< plug - in  className = " etc.ConverterPlugIn "   />

日期字段往往会给我们的开发带来麻烦,其实在Struts应用程序里,只要把这些转换类搞熟了,总可以找到很方便的办法。常见的问题还有如何指定日期输入格式,怎样处理java.util.Date的转换,等等,在这个链接里有解决这些问题的方法,道理都是一样的。