Hibernate Validator, ResourceBundleLocator costume e Primavera
-
10-10-2019 - |
Domanda
sto cercando di ignorare ResourceBundleLocator difetto nella convalida di ibernazione 4.1. Finora funziona perfettamente, ma gli unici esempi di utilizzo comprendono il codice Java per creare un'istanza di ValidationFactory.
Quando si utilizza un'applicazione web con la convalida di primavera Hibernate è configurato automaticamente (solo il adatto ibernazione convalida * file .jar dovrebbe esistere ed è usato automaticamente). Come posso sostituire ResourceBundleLocator in questo scenario? Non vedo alcun modo di specyfing mia ResourceBundleLocator personalizzato in qualsiasi file di proprietà o applicationContext.xml.
Soluzione
Il metodo magico che fa il lavoro richiesto è LocalValidatorFactoryBean # setValidationMessageSource (MessageSource MessageSource) .
Prima di tutto, il contratto del metodo: -
Specifica una consuetudine Primavera MessageSource per la risoluzione di convalida messaggi, invece di basarsi su JSR-303 di predefinito fagotto "ValidationMessages.properties" nel classpath. Questo può fare riferimento a una contesto Primavera condiviso "MessageSource" fagiolo, oa qualche messa a punto speciale per MessageSource scopi di convalida unico.
Nota: Questa funzione richiede Sospensione Validator 4.1 o superiore alla classpath. Si può comunque utilizzare un fornitore di convalida diverso, ma Hibernate Validator di ResourceBundleMessageInterpolator classe deve essere accessibile durante configurazione.
Specificare questa proprietà o "MessageInterpolator", non entrambi. Se si vorrebbe costruire un costume MessageInterpolator, considerare derivante da Hibernate Validator di ResourceBundleMessageInterpolator e passando uno Spring MessageSourceResourceBundleLocator quando si costruisce il vostro interpolatore.
È possibile specificare le message.properties personalizzati (o .xml) invocando questo metodo ... così ...
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
Altri suggerimenti
Ecco una soluzione se si vuole mescolare i messaggi di validazione di sospensione esistenti e messaggi di convalida personalizzato:
<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>
(vedi Web framework MVC convalida sezione e Configurazione di un provider di Bean Validation nella documentazione primavera)
Grazie @ Lu55, in base alla risposta che ho risolto il mio problema !!
Ho appena convertito a una classe di configurazione, e sto postando qui solo nel caso in cui nessun altro bisogno:
Importa dettaglio: ha funzionato per me con ReloadableResourceBundleMessageSource, ma non ha funzionato con ResourceBundleMessageSource. Io non so perché.
@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;
}
}
All'interno la mia risorsa cartella ho lima message.properties.