java Hibernate Validator、自定义 ResourceBundleLocator 和 Spring
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4186556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate Validator, custom ResourceBundleLocator and Spring
提问by Pma
I'm trying to override default ResourceBundleLocator in hibernate validation 4.1. So far it works perfectly, but the only examples of its usage include java code to instantiate ValidationFactory.
我正在尝试覆盖休眠验证 4.1 中的默认 ResourceBundleLocator。到目前为止,它运行良好,但其使用的唯一示例包括实例化 ValidationFactory 的 Java 代码。
When using a web application with spring hibernate validation is automatically configured (only the suitable hibernate validation *.jar file should exist and it is automatically used). How can i substitute ResourceBundleLocator in that scenario? I do not see any way of specyfing my custom ResourceBundleLocator in any properties or applicationContext.xml file.
当使用带有 spring 休眠验证的 web 应用程序时,会自动配置(只有合适的休眠验证 *.jar 文件应该存在并自动使用)。在这种情况下,我如何替换 ResourceBundleLocator?我没有看到在任何属性或 applicationContext.xml 文件中指定我的自定义 ResourceBundleLocator 的任何方式。
回答by dira
The magic method that does the required job is LocalValidatorFactoryBean#setValidationMessageSource(MessageSource messageSource).
完成所需工作的魔法方法是LocalValidatorFactoryBean#setValidationMessageSource(MessageSource messageSource)。
First of all, contract of the method:-
首先,合同的方法: -
Specify a custom Spring MessageSource for resolving validation messages, instead of relying on JSR-303's default "ValidationMessages.properties" bundle in the classpath. This may refer to a Spring context's shared "messageSource" bean, or to some special MessageSource setup for validation purposes only.
NOTE: This feature requires Hibernate Validator 4.1 or higher on the classpath. You may nevertheless use a different validation provider but Hibernate Validator's ResourceBundleMessageInterpolator class must be accessible during configuration.
Specify either this property or "messageInterpolator", not both. If you would like to build a custom MessageInterpolator, consider deriving from Hibernate Validator's ResourceBundleMessageInterpolator and passing in a Spring MessageSourceResourceBundleLocator when constructing your interpolator.
指定用于解析验证消息的自定义 Spring MessageSource,而不是依赖于 JSR-303 的类路径中的默认“ValidationMessages.properties”包。这可能是指 Spring 上下文的共享“messageSource”bean,或仅用于验证目的的某些特殊 MessageSource 设置。
注意:此功能需要类路径上的 Hibernate Validator 4.1 或更高版本。您仍然可以使用不同的验证提供程序,但在配置期间必须可以访问 Hibernate Validator 的 ResourceBundleMessageInterpolator 类。
指定此属性或“messageInterpolator”,而不是两者。如果您想构建自定义 MessageInterpolator,请考虑从 Hibernate Validator 的 ResourceBundleMessageInterpolator 派生并在构建插值器时传入 Spring MessageSourceResourceBundleLocator。
You can specify your custom message.properties(or .xml) by invoking this method... like this...
您可以通过调用此方法来指定您的自定义 message.properties(或 .xml)... 像这样...
my-beans.xml
我的beans.xml
<bean name="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource">
<ref bean="resourceBundleLocator"/>
</property>
</bean>
<bean name="resourceBundleLocator" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>META-INF/validation_errors</value>
</list>
</property>
</bean>
validation_errors.properties
validation_errors.properties
javax.validation.constraints.NotNull.message=MyNotNullMessage
Person.java
人.java
class Person {
private String firstName;
private String lastName;
@NotNull
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
BeanValidationTest.java
BeanValidationTest.java
public class BeanValidationTest {
private static ApplicationContext applicationContext;
@BeforeClass
public static void initialize() {
applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/spring/webmvc-beans.xml");
Assert.assertNotNull(applicationContext);
}
@Test
public void test() {
LocalValidatorFactoryBean factory = applicationContext.getBean("validator", LocalValidatorFactoryBean.class);
Validator validator = factory.getValidator();
Person person = new Person();
person.setLastName("dude");
Set<ConstraintViolation<Person>> violations = validator.validate(person);
for(ConstraintViolation<Person> violation : violations) {
System.out.println("Custom Message:- " + violation.getMessage());
}
}
}
Outupt:Custom Message:- MyNotNullMessage
输出:Custom Message:- MyNotNullMessage
回答by Thomas Vanstals
Here is a solution if you want to mix the existing hibernate validation messages and custom validation messages :
如果您想混合现有的休眠验证消息和自定义验证消息,这是一个解决方案:
<mvc:annotation-driven validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="i18n,iso-i18n,org.hibernate.validator.ValidationMessages" />
<property name="useCodeAsDefaultMessage" value="true" />
</bean>
(see Web MVC framework Validation sectionand Configuring a Bean Validation Providerin Spring documentation)
(请参阅Web MVC 框架验证部分和Spring 文档中的配置 Bean 验证提供程序)
回答by lgonzales
Thank you @Lu55, based on your answer I solved my problem!!
谢谢@Lu55,根据你的回答我解决了我的问题!!
I just converted to a Configuration class, and I am posting here just in case anyone else need:
我刚刚转换为 Configuration 类,我在这里发布以防其他人需要:
Import detail: it worked for me with ReloadableResourceBundleMessageSource, but it did not work using ResourceBundleMessageSource. I am not sure why.
导入详细信息:它对我使用 ReloadableResourceBundleMessageSource,但它不适用于 ResourceBundleMessageSource。我不知道为什么。
@Configuration
public class ErrorConfig {
@Bean
public Validator validatorFactory (MessageSource messageSource) {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.setValidationMessageSource(messageSource);
return validator;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.addBasenames("classpath:org.hibernate.validator.ValidationMessages","classpath:message");
bean.setDefaultEncoding("UTF-8");
return bean;
}
}
Inside my resource folder I have message.properties file.
在我的资源文件夹中,我有 message.properties 文件。