2 votes

Échec de la conversion de la valeur de propriété de type 'java.lang.String' en type requis 'java.time.LocalDate' pour la propriété 'date' dans le formulaire Thymeleaf

    date :  

Contrôleur pour le formulaire ci-dessus

@PostMapping("/hi")
fun testum(@ModelAttribute datum: Datum) {
    println(datum)
}

Classe pojo simple

class Datum(
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        var date: LocalDate? = null
)

Je essaie d'envoyer une date dans le formulaire mais je reçois cette exception :

Resolved exception caused by Handler execution: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'datum' on field 'date': rejected value [2018-06-20]; codes [typeMismatch.datum.date,typeMismatch.date,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [datum.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2018-06-20'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2018-06-20]]

Mais si je change le type de LocalDate à String, cela fonctionne bien. Je veux mapper la date qui se trouve dans le formulaire à la propriété date de la classe Datum. Est-ce que quelqu'un peut m'aider avec ça ? Des liens ? Merci.

Ce lien ne m'a pas aidé problème similaire

1voto

Yussef Points 422

J'ai juste créé votre exemple en utilisant ceci comme contrôleur:

@Controller
public class StackOverflow {

@GetMapping("/stack")
public String template(Model m) {
    m.addAttribute("datum", new Datanum());
    return "stackoverflow.html";
}

@PostMapping("/stack2")
public String testum(@ModelAttribute Datanum user) {
    System.out.println(user.getDate());
    return null;
}
}

ceci comme vue:

Insert title here

            date :  

et ceci comme Bean

   import java.time.LocalDate;

   import org.springframework.format.annotation.DateTimeFormat;

   public class Datanum{
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDate date;

        public LocalDate getDate() {
            return date;
        }

        public void setDate(LocalDate date) {
            this.date = date;
        }
    }

et ça a fonctionné:

enter image description here

enter image description here

La différence que je vois est que vous utilisez var sur votre Bean

  var date: LocalDate? = null

Je pense que c'est Java 10, n'est-ce pas? pourquoi ne pas essayer d'utiliser

le bean comme je l'ai fait, peut-être que cela pourrait vous aider.

Au lieu de var, utilisez LocalDate

j'espère que cela fonctionne

0voto

Gyuhyeon Lee Points 344

C'est une vieille question, mais je laisse une réponse juste pour les lecteurs futurs.
Ce n'est pas un problème avec Thymeleaf, mais plus un problème de liaison @DateTimeFormat.
L'exemple dans la question ci-dessus fonctionnera si la classe Datum est modifiée comme ceci:

Solution 1.

class Datum {
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    var date: LocalDate? = null
}

notez que le champ date a été déplacé de la déclaration dans le constructeur principal dans le corps de la classe.
(remarquez le changement de Datum (...) à Datum {...})

Solution 2.

class Datum (
   @field:DateTimeFormat(pattern = "yyyy-MM-dd") var date: LocalDate? = null
)

si vous devez le déclarer à l'intérieur du constructeur en raison de l'avoir comme data class ou d'autres raisons, vous devez annoter en utilisant les cibles d'utilisation des annotations.
CEPENDANT, méfiez-vous que la Solution 2 ne fonctionne pas toujours. Je ne peux pas reproduire dans un projet d'exemple - mais dans un projet réel, il y avait un problème où @field:DateTimeFormat ne liait pas correctement la chaîne de paramètres de requête à l'objet Date. Parfois ça marchait et parfois non, ce qui le rendait très difficile à déboguer.
Quand cela ne fonctionnait pas, il crachait des erreurs comme Validation failed for object='Datum'. Error count: 1, tandis que revenir à la Solution 1 fonctionnait toujours. À chaque fois que nous compilions à nouveau, la Solution 2 fonctionnait parfois et se cassait aléatoirement sans aucun changement de code.
Nous avons donc décidé de strictement mettre les champs annotés @DateTimeFormat dans la déclaration du corps de la classe pour garantir que cela fonctionne.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X