More recent versions of the Spring framework introduced conversion and formatting services to take care of these tasks, somehow leaving the property editors system behind. However, the issue reported is unfortunately still present: the default DateFormatter is unable to properly convert an empty string to a null Date object. What I find extremely irritating is that the Spring documentation contains a date formatter snippet example where the proper guard clauses are implemented for both conversions (to and from strings). This discrepancy between the framework implementation and the framework documentation really drives me insane, so much that I could even try to submit a patch as soon as I find some time to devote to the task.
In the meantime, my suggestion to everyone encountering this problem while using a modern version of the Spring framework is to subclass the default DateFormatter and override its parse method (its print method, too, if it's needed) so as to add a guard clause in the fashion of the one shown in the documentation.
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);
}
}
Then, some modifications must be applied to the XML Spring configuration: a conversion service bean must be defined, and the corresponding attribute in the annotation-driven element in the mvc namespace must be properly set.
<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>
To provide a specific date format, the pattern property of the DateFormatter bean must be properly set.
<beans:bean class="com.example.util.DateFormatter">
<beans:property name="pattern" value="yyyy-MM-dd" />
</beans:bean>