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!

30
demandé sur Joaquín L. Robles 2011-01-26 18:03:09

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));
}
48
répondu Chin Huang 2011-01-26 16:31:43

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>
5
répondu Giulio Piancastelli 2015-04-08 14:38:28