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?
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>
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
configurationEn 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.
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
.
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){
//...
}