在Struts中,
当输入页面中含有日期字符串时,如果Form中对于的字段为Date类型,则会出现“argument type mismatch”错误。

原因:
Struts的ActionServlet在接受到页面的请求后,会调用RequestUtils.populate方法对Form进行填值,而此方法又调用到BeanUtils.populate方法,而该方法进行填值时对不同类型的会进行转换,而默认的ActionServlet并没有注册相应的转换函数,所以会导致转换出现错误。

解决方法:

  • 方法1:
    Form中的日期使用String类型,在Action中自己处理String到Date的类型转换。
  • 方法2:Form中使用java.util.Date类型,自定义一个日期转换类DateConverter(需要实现Converter接口),然后在自定义的ActionServlet或者Action基类中注册DateConverter:ConvertUtils.register(new DateConverter(), Date.class)。

看了下commons-beanutils的源码发现:BeanUtilsBean含有一个beansByClassLoader静态常量,加载时会初始化一个BeanUtilsBean实例,每次调用getInstance方法返回的都是同一个BeanUtilsBean实例。所以可以在任意地方注册 DateConverter,但要确保在调用BeanUtils.populate方法前已经注册DateConverter,所以应该可以在一个初始化的Servlet中注册,或者在Form类里面静态注册。

下面是DateConverter.java

/* @(#) DateConverter.java			2010-5-11
 * 
 * Copyright (c) 2002-2010 Maxtech, Inc.
 * 66 ZhongGuanCun East Road, BeiJing, 100086, China
 * All rights reserved.
 * 
 * This software is the confidential and proprietary information of
 * Maxtech, Inc. ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Maxtech.
 * 
 */
package cn.com.maxtech.util;
 
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
 
import org.apache.commons.beanutils.Converter;
 
 
/**
 * @TODO
 * @author liufei
 */
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){
 
                }
            }
            return dateObj;
        }else{
            return null;
        }
    }
 
}

可以在Action中注册,例如:

public class DateAction extends StrutsAction {
.....
      static {
		ConvertUtils.register(new DateConverter(), Date.class);
	}
.....
}

或者Form内:

public class DateForm extends ActionForm {
......
 static {
		ConvertUtils.register(new DateConverter(), Date.class);
	}
......
}