Conversion d'une chaîne vide en objet Date null avec Spring
J'ai un champ de formulaire qui doit être converti en objet Date, comme suit:
<form:input path="date" />
Mais je veux obtenir une valeur null lorsque ce champ est vide, au lieu de cela je reçois:
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';
Existe-t-il un moyen facile d'indiquer que les chaînes vides doivent être converties en null? Ou devrais-je écrire mon propre PropertyEditor?
Merci!
2 réponses
Spring fournit un PropertyEditor nommé CustomDateEditor que vous pouvez configurer pour convertir une chaîne vide en une valeur null. Vous devez généralement l'enregistrer dans une méthode @InitBinder
de votre contrôleur:
@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));
}
Des versions plus récentes du framework Spring ont introduit des services de conversion et de formatage pour s'occuper de ces tâches, laissant en quelque sorte le système des éditeurs de propriétés derrière. Cependant, le problème signalé est malheureusement toujours présent: la valeur par défaut DateFormatter
impossible de convertir correctement une chaîne vide en null
Date
objet. Ce que je trouve extrêmement irritant, c'est que la documentation de printemps contient un exemple d'extrait de formateur de date où les clauses de garde appropriées sont implémenté pour les deux conversions (vers et depuis des chaînes). Cet écart entre l'implémentation du framework et la documentation du framework me rend vraiment fou, à tel point que je pourrais même essayer de soumettre un patch dès que je trouve du temps à consacrer à la tâche.
En attendant, ma suggestion à tous ceux qui rencontrent ce problème lors de l'utilisation d'une version moderne du framework Spring est de sous-classer le DateFormatter
par défaut et de remplacer sa méthode parse
(sa méthode print
, aussi, si c'est nécessaire) afin d'ajouter une clause de garde à la mode de celle montrée dans la 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);
}
}
Ensuite, certaines modifications doivent être appliquées à la configuration XML Spring: un bean de service de conversion doit être défini, et l'attribut correspondant dans l'élément annotation-driven
dans l'espace de noms mvc
doit être correctement défini.
<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>
Pour fournir un format de date spécifique, la propriété pattern
du bean DateFormatter
doit être correctement définie.
<beans:bean class="com.example.util.DateFormatter">
<beans:property name="pattern" value="yyyy-MM-dd" />
</beans:bean>