Pregunta

Estoy intentando anular ResourceBundleLocator defecto en la validación de hibernación 4.1. Hasta ahora funciona perfectamente, pero los únicos ejemplos de su uso incluyen el código de Java para crear una instancia ValidationFactory.

Cuando se utiliza una aplicación web con la validación de hibernación de resorte está configurado de forma automática (en caso de existir sólo la validación de hibernación adecuada * .jar y se utiliza de forma automática). ¿Cómo puedo sustituir ResourceBundleLocator en ese escenario? No veo ninguna manera de specyfing mi ResourceBundleLocator costumbre en cualquier archivo de propiedades o applicationContext.xml.

¿Fue útil?

Solución

El método mágico que hace el trabajo requerido es LocalValidatorFactoryBean # setValidationMessageSource (MessageSource MessageSource) .

En primer lugar, el contrato del método: -

Especificar una costumbre primavera MessageSource para la resolución de validación mensajes, en lugar de depender por defecto de JSR-303 bundle "ValidationMessages.properties" en la ruta de clase. Esto puede referirse a una Primavera contexto es compartido "MessageSource" frijol, oa alguna configuración especial para MessageSource fines de validación solamente.

NOTA: Esta función requiere Hibernate Validador de 4.1 o más en el ruta de clase. Es posible utilizar, sin embargo, una proveedor de validación diferente, pero Validador de hibernación ResourceBundleMessageInterpolator clase debe ser accesible durante de configuración.

Especifique esta propiedad o "MessageInterpolator", no ambos. Si que le gustaría construir una costumbre MessageInterpolator, considere la posibilidad de derivar Validador de hibernación de ResourceBundleMessageInterpolator y pasando en un resorte MessageSourceResourceBundleLocator cuando se construye el interpolador.

Puede especificar sus message.properties personalizados (o .xml) mediante la invocación de este método ... así ...

mi-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

Otros consejos

Aquí es una solución si usted quiere mezclar los mensajes de validación de hibernación existentes y los mensajes de validación personalizada:

<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>

(ver web MVC marco de validación de la sección y Configuración de un proveedor Bean Validation en la documentación de la primavera)

Gracias @ LU55, en base a su respuesta he resuelto mi problema !!

acabo de convertir en una clase de configuración, y yo estoy publicando aquí por si acaso alguien más necesidad:

Importar detalle: a mí me funcionó con ReloadableResourceBundleMessageSource, pero no funcionó usando ResourceBundleMessageSource. No estoy seguro de por qué.

@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;
    }
}

Dentro de mi carpeta de recursos tengo message.properties archivo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top