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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top