Spring 数据 REST(使用 Spring 引导)- Hibernate 验证本地化

Spring Data REST(using Spring Boot) - Hibernate Validation Localization

我目前正在评估 Spring Data REST
我从这个简单的例子开始:link

开箱即用。但现在,在下一步中,我想尝试一些验证,看看框架如何反应。所以我简单地注释了 Personclass:

@Size(min = 2, message = "{test.error.message}")
private String firstName;

验证本身正在运行,我收到一条错误消息。如果我在 class 路径的根目录中放置一个名为 ValidationMessages.properties 的文件,该消息就会得到解决(参见 here 原因)。


现在,我不想将文件放在根目录中,而是将它们放在子文件夹中(例如 lang/ValidationMessages.properties)并使用 Spring MessageSource 而不是默认方法。

经过一番研究,我发现了以下问题: MessageInterpolator in Spring

不幸的是,使用以下 bean 定义不起作用:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">

  <bean id="messageSource"
            class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basenames">
      <list>
        <value>lang/ValidationMessages</value>
      </list>
    </property>
  </bean>

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

pom.xml里面对应的依赖(以防万一):

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

有人知道我错过了什么吗?可能是因为我没有使用 Spring MVC,而是使用 Spring Data REST?如果是,是否有办法让它发挥作用?

经过一些额外的调查(以及大量的搜索),我找到了解决问题的方法。


问题

Hibernate 不为验证器工厂使用 bean,这就是为什么 LocalValidatorFactoryBean 没有被使用的原因。

有关详细信息,请查看 org.hibernate.cfg.beanvalidation.TypeSafeActivator#activate(ActivationContext activationContext)


第一种方法

您实际上可以使用此 属性 指定要使用的工厂:javax.persistence.validation.factory

不幸的是,这还不能在 Spring Boot 的 application.properties.
中使用 (看这个Issue on GitHub


解决方案

使用链接的 GitHub 问题中描述的解决方法有效。 您必须为 Hibernate 提供配置:

@Configuration
public class HibernateConfig extends HibernateJpaAutoConfiguration {

  @Autowired
  private ValidatorFactory validator;

  @Override
  protected void customizeVendorProperties(Map<String, Object>     vendorProperties) {
    super.customizeVendorProperties(vendorProperties);
    vendorProperties.put("javax.persistence.validation.factory", validator);
  }
}

使用这种方法可以正确解析消息。

HibernateJpaAutoConfiguration 无法再工作(在 sprint 引导 2.10 之后)

如果你使用 Spring Boot 2.1.0+:

@Configuration
@Lazy
class SpringValidatorConfiguration {

    @Bean
    @Lazy
    public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(final Validator validator) {
        return new HibernatePropertiesCustomizer() {

            @Override
            public void customize(Map<String, Object> hibernateProperties) {
                hibernateProperties.put("javax.persistence.validation.factory", validator);
            }
        };
    }
}

想法来自Spring Boot 2.0.0 M6 - Add Hibernate Interceptor