Spring 数据 REST(使用 Spring 引导)- Hibernate 验证本地化
Spring Data REST(using Spring Boot) - Hibernate Validation Localization
我目前正在评估 Spring Data REST。
我从这个简单的例子开始:link
开箱即用。但现在,在下一步中,我想尝试一些验证,看看框架如何反应。所以我简单地注释了 Person
class:
@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
和
我目前正在评估 Spring Data REST。
我从这个简单的例子开始:link
开箱即用。但现在,在下一步中,我想尝试一些验证,看看框架如何反应。所以我简单地注释了 Person
class:
@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
和