Не удалось прочитать сообщения проверки из файла messages.properties

Я создаю простое приложение Spring REST, и ниже приведен мой класс конфигурации Spring;

@Configuration
@EnableWebMvc
@ComponentScan( basePackages = "com.example.spring" )
public class AppConfig {    
    @Bean
    public ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:/messages");
        return messageSource;
    }   
}

И это то, что я сделал в своем классе контроллера;

@RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResponseEntity<Map<String, String>> createEmployee(@Valid @RequestBody EmployeeModel employeeModel, BindingResult result) {
        if (result.hasErrors()) {
            System.out.println("Errors: " + result.getAllErrors());
            Map<String, String> response = new HashMap<>();
            response.put("status", "failure");
            return new ResponseEntity<>(response, HttpStatus.OK);
        }
        employeeService.createEmployee(employeeModel);
        Map<String, String> response = new HashMap<>();
        response.put("status", "success");
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

Я аннотировал свое поле имени в EmployeeModel, как показано ниже;

@NotEmpty
@Column(name = "name")
private String name;

А это мой файл messages.properties, который находится в папке src/main/resources.

NotEmpty.employeeModel.name = Employee name is required.

Но я не могу прочитать это сообщение об ошибке, я получаю только сообщение по умолчанию для @NotEmpty.

Я даже пробовал со следующей конфигурацией;

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("classpath:/messages");
    return messageSource;
}

Пожалуйста, помогите мне с этим!


person karthi    schedule 28.06.2017    source источник
comment
вы когда-нибудь получали ответ на это? У меня точно такая же проблема, и ни одно из приведенных ниже предложений не решает ее.   -  person szxnyc    schedule 27.03.2018


Ответы (5)


Ну, может быть, немного поздно, но это определенно сработало для меня.

Попробуйте изменить конфигурацию MessageSource на эту:

@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasenames("classpath:/messages");
    messageSource.setUseCodeAsDefaultMessage(false);
    messageSource.setCacheSeconds((int) TimeUnit.HOURS.toSeconds(1));
    messageSource.setFallbackToSystemLocale(false);
    return messageSource;
}

И ваш LocalValidatorFactoryBean должен быть таким же, каким вы его уже определили.

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

Я тестировал с использованием версий Spring 5.0.1.Final и Hibernate Validator 5.4.2.Final.

person Jose-Rdz    schedule 29.12.2017
comment
Это не работает. Если он у вас как-то работает, можете ли вы поделиться всем кодом где-нибудь, например, на github? - person szxnyc; 27.03.2018
comment
Это работает, вы можете проверить конфигурацию в этом рабочем проекте . Прежде чем отдать отрицательный голос, возможно, вам следует приложить усилия к тестированию и поделиться своими результатами, а не ожидать, что другие постараются за вас. - person Jose-Rdz; 10.04.2018
comment
Я сделал. Здесь и Здесь. Я пришел к выводу, что это относится только к Spring MVC (как и в вашем примере). Это НЕ относится к обычным полезным нагрузкам Json (например, REST API). Чтобы заставить это работать, мне пришлось написать свой собственный код, см. здесь. - person szxnyc; 10.04.2018
comment
Хорошо, если я понимаю вашу точку зрения по обычным полезным нагрузкам JSON... вы можете найти рабочий пример проверки для полезных нагрузок JSON здесь в методах, использующих @RequestBody... нет такой разницы между Spring MVC и REST API... кстати, если вы считаете свой код правильным подходом, возможно, вы могли бы опубликовать свой ответ, чтобы другие могли извлечь из него пользу... - person Jose-Rdz; 11.04.2018
comment
Это помогло мне! У меня возникла проблема, о которой сообщалось в вопросе, после обновления spring (и безопасности sprig) с 3 до 5 и спящего режима с 5 до 6 и гораздо более незначительных обновлений .... сообщения из файла свойств начали не обнаруживаться и не отображаться (до обновления получилось) СПАСИБО! - person supertramp; 31.10.2018

Может поможет, если еще открыто. Наткнулся на это для аналогичного случая, когда я решил его, явно используя интерполятор:

 <!-- Messagesource for locales -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <util:list>
                <value>classpath:locales/messages/validation</value>
            </util:list>
        </property>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <bean id="resourceBundleMessageInterpolator"
          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>

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

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

в отличие от того, что также предлагалось в других темах, учитывая предполагаемую автоматическую инъекцию через:

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

С вышеизложенным мне удалось использовать заполнители в файлах свойств проверки, также используя скобки: т.е.:

@NotNull(message = "{message.notnull}")

Также следующие подсказки тем были обязательными для меня:

Почему замена аргумента интерполяции сообщений Spring с использованием Hibernate Validator не работает? Как использовать проверку аннотаций в Spring с сообщением об ошибке, полученным из файла свойств?

person TheSees    schedule 03.08.2017

Вам нужно сказать validator, чтобы он использовал ваш messageSource.

@Bean
public javax.validation.Validator validator() {
    final LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
    factory.setValidationMessageSource(messageSource());
    return factory;
}

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("classpath:/messages");
    return messageSource;
}

И укажите ключ сообщения на вашей модели:

@NotEmpty(message = "{NotEmpty.employeeModel.name}")
private String name;
person Bohdan Levchenko    schedule 28.06.2017
comment
Не могли бы вы также предоставить код для bean-компонента MessageSource. - person karthi; 28.06.2017
comment
@karthi Я использовал ваш код для определения bean-компонента messageSource. - person Bohdan Levchenko; 28.06.2017
comment
@karthi хм, попробуйте использовать factory.setValidationMessageSource(messageSource()); вместо инъекции в качестве параметра метода. Я изменил ответ, чтобы отразить этот путь. - person Bohdan Levchenko; 28.06.2017
comment
Нужно ли нам использовать компонент Validator где-либо еще, как описано здесь ссылка - person karthi; 28.06.2017
comment
Теперь он дает мне ключ сообщения в качестве сообщения об ошибке. Это все еще не работает. - person karthi; 28.06.2017

старый вопрос, но это сработало для меня:

    @Bean
    public LocalValidatorFactoryBean localValidatorFactoryBean(final MessageSource messageSource) {
        final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setValidationMessageSource(messageSource);
        return localValidatorFactoryBean;
    }
person John Tribe    schedule 29.10.2018

Сделав все правильно, применив все исправления, упомянутые в Stack Overflow, и потратив несколько часов на то, чтобы заставить его работать, я, наконец, смог исправить это, добавив ниже в свой файл messages.properties.

"# suppress inspection "UnusedProperty" for whole file"

Обратите внимание, что я использую intellij, и по какой-то странной причине он не читал мои сообщения.

person Rahul    schedule 29.11.2018