9

我正在尝试覆盖休眠验证 4.1 中的默认 ResourceBundleLocator。到目前为止,它工作得很好,但其用法的唯一示例包括用于实例化 ValidationFactory 的 java 代码。

当使用带有 spring hibernate 验证的 web 应用程序时,会自动配置(只有合适的 hibernate 验证 *.jar 文件应该存在并自动使用)。在那种情况下,我该如何替换 ResourceBundleLocator?我看不到任何在任何属性或 applicationContext.xml 文件中指定我的自定义 ResourceBundleLocator 的方式。

4

3 回答 3

19

完成所需工作的神奇方法是LocalValidatorFactoryBean#setValidationMessageSource(MessageSource messageSource)

首先,方法的合同:-

指定一个自定义 Spring MessageSource 来解析验证消息,而不是依赖于类路径中 JSR-303 的默认“ValidationMessages.properties”包。这可能是指 Spring 上下文的共享“messageSource”bean,或仅用于验证目的的某些特殊 MessageSource 设置。

注意:此功能需要类路径上的 Hibernate Validator 4.1 或更高版本。您仍然可以使用不同的验证提供程序,但 Hibernate Validator 的 ResourceBundleMessageInterpolator 类必须在配置期间可访问。

指定此属性或“messageInterpolator”,而不是两者。如果您想构建自定义 MessageInterpolator,请考虑从 Hibernate Validator 的 ResourceBundleMessageInterpolator 派生并在构建插值器时传入 Spring MessageSourceResourceBundleLocator。

您可以通过调用此方法来指定您的自定义 message.properties(或 .xml)......就像这样......

我的豆类.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

人.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());
        }
    }

}

输出: Custom Message:- MyNotNullMessage

于 2010-11-22T16:13:44.863 回答
5

如果您想混合现有的休眠验证消息和自定义验证消息,这是一个解决方案:

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

(请参阅Web MVC 框架验证部分和Spring 文档中的配置 Bean 验证提供程序)

于 2014-03-26T08:33:12.527 回答
1

谢谢@Lu55,根据你的回答我解决了我的问题!!

我刚刚转换为一个配置类,我在这里发布以防万一其他人需要:

导入详细信息:它适用于 ReloadableResourceBundleMessageSource,但它不适用于 ResourceBundleMessageSource。我不确定为什么。

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

在我的资源文件夹中,我有 message.properties 文件。

于 2018-07-31T10:01:06.820 回答