web-dev-qa-db-fra.com

Le message de validation Spring Boot n'est pas résolu

J'ai du mal à résoudre mon message de validation.

J'ai cherché et lu sur le Web et SO depuis quelques heures maintenant, je veux associer la question avec la réponse marquée de Personnaliser l'erreur de validation du printemps

J'ai un MessageSource bean défini et le messages.properties il est lu correctement, car je l'utilise également pour le texte normal à affiché avec th:text="#{some.prop.name}, ce qui fonctionne très bien. C'est juste l'erreur de validation qui ne fonctionnera pas comme il se doit. Je suis sûr que c'est une erreur stupide que je néglige ... La validation elle-même fonctionne bien.

Contrainte:

@NotEmpty(message="{validation.mail.notEmpty}")
@Email()
private String mail;

messages.properties:

# Validation
validation.mail.notEmpty=The mail must not be empty!

Partie du modèle:

<span th:if="${#fields.hasErrors('mail')}" th:errors="*{mail}"></span>

Le texte affiché:

{validation.mail.notEmpty}

J'ai essayé beaucoup de variantes, le tout sans succès.

@NotEmpty(message="validation.mail.notEmpty")
@NotEmpty(message="#{validation.mail.notEmpty}")

Affiche simplement la valeur exacte de la chaîne de messages, pas d'analyse.

<span th:if="${#fields.hasErrors('mail')}" th:errors="${mail}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{mail}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{*{mail}}"></span>
<span th:if="${#fields.hasErrors('mail')}" th:errors="#{__*{mail}__}"></span>

Entraînera une erreur.


MODIFIER:

Après le débogage, je suis tombé sur ceci:

Classe: org.springframework.context.support.MessageSourceSupport

Méthode: formatMessage(String msg, Object[] args, Locale locale)

sera appelé avec

formatMessage("{validation.mail.notEmpty}", null, locale /*German Locale*/)

Et il s'exécutera dans if (messageFormat == INVALID_MESSAGE_FORMAT) {

Donc ... mon format de message n'est pas correct. C'est hors de ma portée/connaissance. Quelqu'un sait ce que cela signifie?

16
Korashen

Il semble que la définition LocalValidatorFactoryBean soit manquante dans la configuration de votre application. Ci-dessous, vous trouverez un exemple de classe Application qui définit deux beans: LocalValidatorFactoryBean et MessageSource qui utilise le fichier messages.properties.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

@SpringBootApplication
public class Application {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Une fois le bean LocalValidatorFactoryBean défini, vous pouvez utiliser un message de validation personnalisé comme:

@NotEmpty(message = "{validation.mail.notEmpty}")
@Email
private String email;

et messages.properties :

validation.mail.notEmpty=E-mail cannot be empty!

et fichier modèle Thymeleaf avec:

<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Name Error</p>

Exemple d'application

https://github.com/wololock/stackoverflow-answers/tree/master/45692179

J'ai préparé un exemple d'application Spring Boot qui reflète votre problème. N'hésitez pas à le cloner et à l'exécuter localement. Il affichera un message de validation traduit si la valeur publiée avec le formulaire ne correspond pas à la validation @NotEmpty Et @Email.

WebMvcConfigurerAdapter configuration

En cas d'extension de WebMvcConfigurerAdapter, vous devrez fournir un validateur en remplaçant la méthode getValidator() de la classe parente, par exemple:

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
@EnableWebMvc
public class WebConfiguration extends WebMvcConfigurerAdapter {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    @Override
    public Validator getValidator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    // other methods...
}

Sinon, si vous définissez LocalValidatorFactoryBean bean à un autre endroit, il sera remplacé et il n'y aura aucun effet.

J'espère que ça aide.

41
Szymon Stepniak

Vous ne savez pas quelle version de Spring Boot vous utilisez. J'utilise Spring boot 2.0.1.RELEASE. Une solution plus claire serait de déplacer tous vos messages de validation vers ValidationMessages.properties. De cette façon, vous n'avez pas à remplacer la Validator() configurée automatiquement et à définir la MessageSource.

15
want2learn

Pour les contrôleurs de repos, vous devrez ensuite ajouter une annotation @Valid sur le corps de la demande du paramètre de méthode. par exemple

@PostMapping
public User create(@Valid @RequestBody User user){
  //...
}
1
A.Mushate