Подтвердить что ты не робот

Преобразование пустой строки в нулевой объект Date с помощью Spring

У меня есть поле формы, которое должно быть преобразовано в объект 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?

Спасибо!

4b9b3361

Ответ 1

Spring предоставляет PropertyEditor с именем CustomDateEditor, который вы можете настроить для преобразования пустой строки в нулевое значение. Обычно вам необходимо зарегистрировать его в методе @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));
}

Ответ 2

В более поздних версиях среды Spring были внедрены службы преобразования и форматирования, чтобы заботиться об этих задачах, как-то оставляя систему редакторов свойств. Тем не менее, проблема, о которой сообщается, к сожалению, все еще присутствует: по умолчанию DateFormatter не может правильно преобразовать пустую строку в null Date объект. То, что я нахожу крайне раздражающим, заключается в том, что документация Spring содержит пример фрагмента дате даты, в котором реализованы правильные предложения охраны для обоих преобразований (в и из строк). Это несоответствие между реализацией фреймворка и фреймворческой документацией действительно сбивает меня с ума, так что я даже могу попытаться отправить патч, как только найду какое-то время, чтобы посвятить эту задачу.

Тем временем мое предложение всем, кто сталкивается с этой проблемой при использовании современной версии фрейма 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 должен быть правильно установлен.

<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 DateFormatter bean.

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