web-dev-qa-db-fra.com

Thymeleaf n'affichant pas les messages d'erreur du formulaire Spring

Je migre une application Spring jsp vers Thymeleaf mais je ne parviens pas à afficher les erreurs de formulaire.

J'utilise SpringTemplateEngine et ThymeleafViewResolver et le rendu des modèles fonctionne . Les valeurs de formulaire sont également renseignées dans des champs de saisie de formulaire.

Jusqu'à présent, la seule chose qui ne fonctionne pas, c'est l'affichage de messages d'erreur de formulaire.

Mon contrôleur ressemble à:

@RequestMapping(method = RequestMethod.POST)
String save(@Valid CustomerForm form, BindingResult bindingResult, Model model, RedirectAttributes redirectAttributes) {
    if (bindingResult.hasErrors()) {
        model.addAttribute("form", form)
        return "app/customers/create"
    }
    ....

J'ai imprimé le bindingResult pour vérifier qu'il contient une erreur:

binding result = org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'customerForm' on field 'name': rejected value []; codes [customerForm.name.NotBlank,name.NotBlank,Java.lang.String.NotBlank,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [customerForm.name,name]; arguments []; default message [name]]; default message [may not be empty]

Quand j'essaie d'afficher une erreur en utilisant: 

<ul>
    <li th:each="e : ${#fields.detailedErrors()}" th:class="${e.global}? globalerr : fielderr">
        <span th:text="${e.global}? '*' : ${e.fieldName}">The field name</span> |
        <span th:text="${e.message}">The error message</span>
    </li>
</ul>

il n'affiche aucune erreur.

J'ai essayé diverses alternatives décrites dans http://www.thymeleaf.org/doc/html/Thymeleaf-Spring3.html#validation-and-error-messages mais sans succès.

Est-ce que je manque quelque chose?

MODIFIER

Remarque J'essaie d'afficher l'erreur dans un formulaire défini via th: object:

<form id="customer-form" action="#" th:action="@{/app/customers}" th:object="${form}" method="post" class="form-horizontal">
    <ul>
        <li th:each="e : ${#fields.detailedErrors()}" th:class="${e.global}? globalerr : fielderr">
            <span th:text="${e.global}? '*' : ${e.fieldName}">The field name</span> |
            <span th:text="${e.message}">The error message</span>
        </li>
    </ul>
</form>
20
Marcel Overdijk

Je pense que vous avez peut-être le même problème que moi - s'il vous plaît voir: 

Là, il est répondu par Daniel Fernandez. Fondamentalement, votre objet formulaire th:object="${form}" est nommé "form"mais votre contrôleur recherche "customerForm" (nom de classe) non"form" (le nom de la variable) 

peut être renommé avec @ModelAttribute("data")

copié à partir de ce lien, utilisez:

public String post(@Valid FormData formData, BindingResult result, Model model){
    // th:object="${formData}"
}

ou

public String post(@Valid @ModelAttribute("data") FormData data, BindingResult result, Model model){
    // th:object="${data}"
} 
47
Gary Hellman

Voici comment je le fais dans mes formulaires:

Pour afficher toutes les erreurs, je mets ceci au début de mon formulaire:

<div class="alert alert-danger" th:if="${#fields.hasErrors('*')}">
    <p th:each="err : ${#fields.errors('*')}" th:text="${err}"></p>    
</div>

et pour chaque erreur, j'ajoute ceci après le champ (bien sûr, changer de champ dans hasErrors pour correspondre au champ testé):

<p th:if="${#fields.hasErrors('vehicle.licensePlate')}" class="label label-danger" th:errors="*{vehicle.licensePlate}">Incorrect LP</p>

Faites-moi savoir si cela fonctionne pour vous?

13
Blejzer

Ajouter à @Blejzer answer: La dénomination du message d'erreur dans le fichier messages.properties doit suivre la convention de dénomination ci-dessous, ainsi la chaîne de message sera renvoyée au lieu de la clé de message:

(Nom de contrainte). (Nom d'objet). (Nom de propriété)

note: nom d'objet pas nom de classe

Par exemple, si vous avez ci-dessous la classe d'utilisateurs:

class User{
    @NotBlank
    String username;

    @Length(min=6)
    String password;
}

supposons dans le contrôleur, nous avons nommé l'objet en cours de validation " utilisateur ", voir @ModelAttribute ("utilisateur"):

@RequestMapping(value = "/signup", method = RequestMethod.POST)
public String signup(@Valid @ModelAttribute("user") User user, BindingResult bindingResult, Model model) {

    if (bindingResult.hasErrors()) {
        return "signup";
    }

    //do some processing

    return "redirect:/index";
}

dans l'extrait de contrôleur ci-dessus, le nom de l'objet est " utilisateur " et non "utilisateur"

Maintenant, pour afficher des messages personnalisés, vous devez nommer le message comme suit:

NotBlank.user.username=User Name is blank
Length.user.password=Password length must be at least 6 letters
0
Ayman Al-Absi