Не удается заставить Hibernate Validator работать с Spring MessageSource - PullRequest
5 голосов
/ 30 июля 2011

Я пытаюсь настроить Hibernate Validator на использование сообщений из источника сообщений Spring.У меня есть следующие настройки в моем 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>

Я пробовал различные подходы к тому, как передать ключ сообщения в средство проверки гибернации (как с так и без включения {}, а также безуказание пользовательского ключа - просто используя ключ по умолчанию:

@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

Однако, когда пустые поля проверены, отображаются сообщенияthis:

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

По какой-то причине ключ сообщения всегда используется - реальное сообщение никогда не ищется. Есть идеи, где я ошибаюсь?

Спасибо,

Рассел

Ответы [ 5 ]

12 голосов
/ 12 июня 2012

Это на некоторое время поставило меня в тупик, но проблема в том, что вам необходимо зарегистрироваться в Spring Validator, который используется для проверки методов @Controller (спасибо этому ответу за это понимание!)

Так что, если вы используете 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 )

4 голосов
/ 13 июня 2012

Это потому, что валидатор Hibernate ищет другое место для распознавателя сообщений об ошибках.

Чтобы проще всего это сделать, я думаю, вы можете создать имя файла "ValidationMessages.properties" и поместить его вваша папка classpath.Затем поместите сообщения об ошибках в этот файл (полученный из validation_errors_en_GB.properties)

Кстати, скобки требуются при указании сообщений об ошибках в классах моделей (message="{validation.too.long}")

1 голос
/ 17 августа 2011

Hibernate Validator ищет другое место для локали.Попробуйте это:

LocaleContextHolder.setLocale (locale);

0 голосов
/ 26 декабря 2018

Это сработало для меня.

<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" />
0 голосов
/ 08 мая 2018

Проверка гибернации не знает о источнике сообщений Spring.Вам нужно будет реализовать MessageInterpolator.Это может выглядеть примерно так:

public class SpringMessageInterpolator implements MessageInterpolator {

    private final MessageResource messageResource;
    private final MessageInterpolator delegate;

    public SpringMessageInterpolator(MessageResource messageResource, MessageInterpolator delegate) {
        this.messageResource = messageResource;
        this.delegate = delegate;
    }

    @Override
    public String interpolate(String messageTemplate, Context context) {
        Locale locale = Locale.getDefault();
        return interpolate(messageTemplate, context, locale);
    }

    @Override
    public String interpolate(String messageTemplate, Context context, Locale locale) {
        try {
            Object[] args = {};
            return databaseMessageResource.getMessage(messageTemplate, args, locale);
        } catch (NoSuchMessageException ex) {
            return delegate.interpolate(messageTemplate, context, locale);
        }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...