使用Spring将空String转换为null Date对象

时间:2011-01-26 15:03:09

标签: java spring spring-mvc

我有一个表单字段应该转换为Date对象,如下所示:

<form:input path="date" />

但是当这个字段为空时我希望得到一个空值,而不是我收到的:

Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'date';
org.springframework.core.convert.ConversionFailedException: Unable to convert value "" from type 'java.lang.String' to type 'java.util.Date';

是否有一种简单的方法来指示空字符串应该转换为null?或者我应该编写自己的 PropertyEditor

谢谢!

3 个答案:

答案 0 :(得分:48)

Spring提供了一个名为CustomDateEditor的PropertyEditor,您可以将其配置为将空String转换为空值。您通常必须在控制器的@InitBinder方法中注册它:

@InitBinder
public void initBinder(WebDataBinder binder) {
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    dateFormat.setLenient(false);

    // true passed to CustomDateEditor constructor means convert empty String to null
    binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}

答案 1 :(得分:6)

更新版本的Spring框架引入了转换和格式化服务来处理这些任务,不知何故让属性编辑器系统落后。但是,遗憾的是,报告的问题仍然存在:默认DateFormatter is unable to properly convertnull Date对象的空字符串。我发现非常恼人的是Spring文档contains a date formatter snippet example where the proper guard clauses are implemented用于两次转换(来自和来自字符串)。框架实现和框架文档之间的这种差异确实让我感到疯狂,甚至在我找到一些时间投入任务时我甚至可以尝试提交补丁。

与此同时,我在使用Spring框架的现代版本时遇到此问题的建议是对默认DateFormatter进行子类化并覆盖其parse方法(其print方法,如果需要的话),以文档中显示的方式添加一个保护条款。

package com.example.util;

import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

public class DateFormatter extends org.springframework.format.datetime.DateFormatter {

    @Override
    public Date parse(String text, Locale locale) throws ParseException {
        if (text != null && text.isEmpty()) {
            return null;
        }
        return super.parse(text, locale);
    }

}

然后,必须对XML Spring配置进行一些修改:必须定义转换服务bean,并且必须正确设置annotation-driven命名空间中mvc元素中的相应属性。 / p>

<mvc:annotation-driven conversion-service="conversionService" />
<beans:bean
    id="conversionService"
    class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <beans:property name="formatters">
        <beans:set>
            <beans:bean class="com.example.util.DateFormatter" />
        </beans:set>
    </beans:property>
</beans:bean>

要提供特定的日期格式,必须正确设置pattern bean的DateFormatter属性。

<beans:bean class="com.example.util.DateFormatter">
    <beans:property name="pattern" value="yyyy-MM-dd" />
</beans:bean>

答案 2 :(得分:0)

使用Spring 5,此错误仍然可能非常错误地发生.........如果您有一个映射的集合,例如这样,请确保集合中的索引正确(这来自Spring中的@initBinder控制器)

if(sm != null && sm.getSapSaleItems() != null) {
        int i = sm.getSapSaleItems().size();
        for (int x = 0; x < i ; x++) {
            binder.registerCustomEditor(Date.class, "salesOrderItems[" + i + "].pickDate",
                    new CustomDateEditor(dateFormatter, true));
            
        }

“ i”应为x)))),导致出现相同的错误,即空字符串无法强制转换为当前日期:

默认消息[salesOrderItems [1] .pickDate]];默认消息[无法将属性'salesOrderItems [1] .pickDate'的'java.lang.String'类型的属性值转换为所需的'java.util.Date'类型;嵌套的异常是org.springframework.core.convert.ConversionFailedException:无法将值“”从类型[java.lang.String]转换为类型[java.util.Date]。嵌套的异常是java.lang.IllegalArgumentException]

jsp代码如下:

<td><form:input cssClass="datepicker" size="10"
                                    path="salesOrderItems[${loopStatus.index}].pickDate" /></td>

...还有另一个可能导致相同误导性错误的原因,即配置相同,如果表单支持对象中没有嵌套的汁液行集合(请参见我的示例)....