Hibernate Validator, ResourceBundleLocator personnalisé et Spring
-
10-10-2019 - |
Question
Je suis en train de passer outre ResourceBundleLocator par défaut dans la validation Mise en veille prolongée 4.1. Jusqu'à présent, il fonctionne parfaitement, mais les seuls exemples de son utilisation incluent du code Java pour instancier ValidationFactory.
Lors de l'utilisation d'une application web avec validation de mise en veille prolongée de ressort est configuré automatiquement (uniquement le fichier Jar de validation de mise en veille prolongée adapté * doit exister et il est utilisé automatiquement). Comment puis-je remplacer ResourceBundleLocator dans ce scénario? Je ne vois aucun moyen de specyfing mon ResourceBundleLocator personnalisé dans un fichier de propriétés ou applicationContext.xml.
La solution
La méthode magique qui fait le travail nécessaire est LocalValidatorFactoryBean # setValidationMessageSource (MessageSource MessageSource) .
Tout d'abord, le contrat de la méthode: -
Spécifiez une coutume printemps MessageSource pour résoudre la validation messages, au lieu de compter sur par défaut de JSR-303 bundle "de ValidationMessages.properties" dans le classpath. Cela peut se référer à un contexte de printemps est partagé haricot « de MessageSource », ou à certains configuration spéciale pour MessageSource des fins de validation seulement.
NOTE: Cette fonction nécessite Hibernate Validator 4.1 ou plus sur la classpath. Vous pouvez néanmoins utiliser un autre fournisseur de validation, mais Hibernate Validator de ResourceBundleMessageInterpolator classe doit être accessible pendant configuration.
Spécifiez cette propriété ou "MessageInterpolator", pas les deux. Si vous souhaitez construire une coutume MessageInterpolator, pensez à dériver de Hibernate Validator de ResourceBundleMessageInterpolator et en passant un ressort MessageSourceResourceBundleLocator lors de la construction de votre interpolateur.
Vous pouvez spécifier vos message.properties personnalisés (ou .xml) en invoquant cette méthode ... comme ça ...
my-beans.xml
<bean name="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource">
<ref bean="resourceBundleLocator"/>
</property>
</bean>
<bean name="resourceBundleLocator" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>META-INF/validation_errors</value>
</list>
</property>
</bean>
validation_errors.properties
javax.validation.constraints.NotNull.message=MyNotNullMessage
Person.java
class Person {
private String firstName;
private String lastName;
@NotNull
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
BeanValidationTest.java
public class BeanValidationTest {
private static ApplicationContext applicationContext;
@BeforeClass
public static void initialize() {
applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/spring/webmvc-beans.xml");
Assert.assertNotNull(applicationContext);
}
@Test
public void test() {
LocalValidatorFactoryBean factory = applicationContext.getBean("validator", LocalValidatorFactoryBean.class);
Validator validator = factory.getValidator();
Person person = new Person();
person.setLastName("dude");
Set<ConstraintViolation<Person>> violations = validator.validate(person);
for(ConstraintViolation<Person> violation : violations) {
System.out.println("Custom Message:- " + violation.getMessage());
}
}
}
Outupt: Custom Message:- MyNotNullMessage
Autres conseils
Voici une solution si vous voulez mélanger les messages et les messages de validation personnalisés validation de mise en veille prolongée existants:
<mvc:annotation-driven validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="i18n,iso-i18n,org.hibernate.validator.ValidationMessages" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
(voir framework MVC Web section validation et Configuration d'un fournisseur de validation Bean dans la documentation Spring)
Merci @ Lu55, en fonction de votre réponse que je résolu mon problème !!
Je viens converti en une classe de configuration, et je suis commentaire ici au cas où quelqu'un d'autre besoin:
Importation détail: il a travaillé pour moi avec ReloadableResourceBundleMessageSource, mais il ne fonctionne pas à l'aide ResourceBundleMessageSource. Je ne sais pas pourquoi.
@Configuration
public class ErrorConfig {
@Bean
public Validator validatorFactory (MessageSource messageSource) {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.addBasenames("classpath:org.hibernate.validator.ValidationMessages","classpath:message");
bean.setDefaultEncoding("UTF-8");
return bean;
}
}
Dans ma ressource dossier que j'ai fichier message.properties.