【问题标题】:Not able to read validation messages from messages.properties file无法从 messages.properties 文件中读取验证消息
【发布时间】:2017-06-28 06:08:36
【问题描述】:

我正在创建一个简单的 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;
}

请帮我解决这个问题!

【问题讨论】:

  • 你有没有得到这个答案?我有完全相同的问题,下面的建议都没有解决它。

标签: spring spring-mvc hibernate-validator spring-restcontroller spring-rest


【解决方案1】:

好吧,也许有点晚了,但这对我来说确实有效。

尝试为此更改您的 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 版本进行了测试。

【讨论】:

  • 这不起作用。如果你让它以某种方式运行,你能在 github 之类的地方分享整个代码吗?
  • 这行得通,您可能想检查此working project 中的配置。在投反对票之前,也许您应该努力测试和分享您的结果,而不是期望其他人为您尝试。
  • 我做到了。 Here 和 Here。我得出的结论是,这仅适用于 Spring MVC(就像您的示例一样)。这不适用于常规 Json 有效负载(即 REST API)。为了让我工作,我必须编写自己的代码,请参阅here。
  • 好吧,如果我从常规 JSON 有效负载中得到您的观点...您可以在使用 @RequestBody 的方法上找到 JSON 有效负载 here 的有效验证示例。 .. Spring MVC 和 REST API 没有这样的区别...顺便说一句,如果您认为您的代码是正确的方法,也许您可​​以发布您的答案,以便其他人可以从中受益...
  • 这对我有帮助!在将 spring(和 sprig 安全性)从 3 升级到 5 并将休眠从 5 升级到 6 以及更多次要升级之后,我遇到了问题中报告的问题.... 来自属性文件的消息开始找不到并且不显示(在升级之前成功了)谢谢!
【解决方案2】:

如果仍然打开可能会有所帮助。 在类似的情况下遇到了这种情况,我明确地使用插值器解决了这个问题:

 <!-- 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}")

以下线程提示对我来说也是必须的:

Why Spring Message Interpolation Argument Replacement using Hibernate Validator don't work? How to use annotation validation in Spring with error message gotten from properties file?

【讨论】:

    【解决方案3】:

    您需要告诉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;
    

    【讨论】:

    • 能否请您也提供 MessageSource bean 的代码。
    • @karthi 我已经使用你的代码来定义 messageSource bean。
    • @karthi 嗯,尝试使用factory.setValidationMessageSource(messageSource()); 而不是注入作为方法参数。我已经修改了答案以反映这种方式。
    • 我们是否需要在此处讨论的其他任何地方使用验证器 bean link
    • 现在它给了我消息键作为错误消息。它仍然无法正常工作。
    【解决方案4】:

    老问题,但这对我有用:

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

    【讨论】:

      【解决方案5】:

      在做正确的一切之后,应用上面提到的所有修复 Stack Overflow 并花了几个小时才让它工作,我终于能够通过在我的 messages.properties 文件中添加以下内容来修复它

      "# suppress inspection "UnusedProperty" for whole file"

      请注意,我正在使用 intellij,但由于某种奇怪的原因,它没有阅读我的消息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-06-28
        • 1970-01-01
        • 2011-01-12
        • 2012-07-23
        • 2023-04-02
        • 2019-07-17
        • 1970-01-01
        相关资源
        最近更新 更多