无法让Hibernate Validator与Spring MessageSource一起使用

时间:2011-07-30 17:30:08

标签: hibernate spring-mvc localization validation

我正在尝试让Hibernate Validator设置为使用来自Spring MessageSource的消息。我在messages-context.xml

中进行了以下设置
<bean id="messageSource"
    class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>WEB-INF/messages/messages</value>
            <value>WEB-INF/messages/exceptions</value>
            <value>WEB-INF/messages/fields</value>
            <value>WEB-INF/messages/buttons</value>
            <value>WEB-INF/messages/validation_errors</value>
        </list>
    </property>
</bean>

<bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="validationMessageSource" ref="messageSource" />
</bean>

<bean id="localeChangeInterceptor"
    class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
    <property name="paramName" value="lang" />
</bean>

<bean id="localeResolver"
    class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
    <property name="defaultLocale" value="en_GB" />
</bean>

我已经尝试了各种方法来解决如何将消息密钥传递给hibernate验证器(包括和不包含{},也没有指定自定义密钥 - 只使用默认密钥:

@NotEmpty(message="validation.required.field")
@Length(max=255, message="{validation.too.long}")
private String firstName;

@NotEmpty(message="{validation.required.field}")
@Length(max=255, message="{validation.too.long}")
private String lastName;

@NotNull
@Past(message="{validation.must.be.past}")
private Date dateOfBirth;

@NotEmpty(message="{validation.required.field}")
@Length(max=255, message="{validation.too.long}")
private String email;

我的validation_errors_en_GB.properties看起来像这样:

validation.required.field=this is a required field
validation.too.long=this field can only take {0} characters
validation.must.be.past=this date has to be in the past 
javax.validation.constraints.NotNull.message=Custom message

但是,当验证空字段时,显示的消息为:

First name      validation.required.field
Last name       {validation.required.field}
Date of birth   may not be null
Email           {validation.required.field}

无论出于何种原因,始终使用消息的密钥 - 实际消息永远不会被查找。知道我哪里错了吗?

谢谢,

罗素

5 个答案:

答案 0 :(得分:12)

这让我感到困惑了一段时间,但问题是你需要向Spring注册用于验证@Controller方法的Validator(感谢this answer获得该洞察力!)

因此,如果您使用XML配置,请执行以下操作:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="messageInterpolator" ref="messageSource"/>
</bean>

<mvc:annotation-driven validator="validator"/> 

如果您使用的是javaconfig,请执行以下操作:

@EnableWebMVC
@Configuration
public MyWebAppContext extends WebMvcConfigurerAdapter {

@Bean
public LocalValidatorFactoryBean validator() {
    LocalValidatorFactoryBean validatorFactoryBean = new LocalValidatorFactoryBean();
    validatorFactoryBean.setValidationMessageSource(messageSource);
    return validatorFactoryBean;
}

@Override
public Validator getValidator() {
    return validator();
}

(见Spring Web MVC framework documentation

答案 1 :(得分:4)

这是因为Hibernate验证器正在查找错误消息解析器的另一个位置。

为了最简单的方法,我认为您可以创建一个文件名“ValidationMessages.properties”并将其放在classpath文件夹中。然后将错误消息放入该文件(来自validation_errors_en_GB.properties

顺便说一下,在模型类(message="{validation.too.long}"

中指定错误消息时需要括号

答案 2 :(得分:1)

Hibernate Validator正在寻找语言环境的不同位置。试试这个:

LocaleContextHolder.setLocale(区域);

答案 3 :(得分:0)

Hibernate验证不了解Spring的MessageSource。您需要实现MessageInterpolator。它可能如下所示:

add_action( 'admin_print_scripts', function() {
    // I'm using NOWDOC notation to allow line breaks and unescaped quotation marks.
    echo <<<'EOT'
<script type="text/javascript">
jQuery(function($){
    // Do stuff here.
});
</script>
EOT;
}, PHP_INT_MAX );

答案 4 :(得分:0)

这对我有用。

<bean id="messageSource"
    class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename">
        <value>i18n/messages</value>
    </property>
</bean>

<bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="messageInterpolator">
        <bean
            class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator">
            <constructor-arg index="0">
                <bean
                    class="org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator">
                    <constructor-arg index="0" ref="messageSource" />
                </bean>
            </constructor-arg>
        </bean>
    </property>
</bean>

<bean
    class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
    <property name="validator" ref="validator" />
</bean>


<mvc:annotation-driven validator="validator" />