[英]How to use a custom message from my .properties file, but using the parameters provided by the @Size annotation?
That should be a simple problem but I couldn't find a straight forward solution. 这应该是一个简单的问题,但我找不到直接的解决方案。
I'm using the Spring Message Resource to provide all the texts on my system from a .properties file. 我正在使用Spring Message Resource从.properties文件中提供我系统上的所有文本。 I need that for internationalization questions and cannot use the default messages from the Spring.
我需要那些国际化问题,不能使用Spring的默认消息。
Here is the problem: 这是问题所在:
I have the following line in my .properties file: 我的.properties文件中有以下行:
validator_invalid_state_name=Invalid name ({min}, {max})
The validation code is: 验证码是:
@Size( min=3, max=5, message="validator_invalid_state_name" )
public String name;
However, when an invalid value is sent to the field, the message is: 但是,当向字段发送无效值时,消息为:
"Invalid name ({min}, {max})" and not "Invalid name (3, 5)" .
“无效的名称({min},{max})”而不是“无效的名称(3,5)” 。
I've tried several solutions without success, for example: 我尝试了几种解决方案但没有成功,例如:
@Size( min=3, max=5, message="{validator_invalid_state_name}" )
@Size( min=3, max=5, message="${validator_invalid_state_name}" )
@Size( min=3, max=5, message="Size.name" ) // with "Size.name=Invalid name ({min}, {max})" in my .properties file
@Size( min=3, max=5, message="{Size.name}" ) //idem
But if I use only 但如果我只使用
@Size( min=3, max=5 )
Then, I get the default message from Spring (that I don't want to use). 然后,我从Spring获取默认消息(我不想使用)。 What I need is very simple: to use my own message from my custom .properties file, but using the parameters provided by the @Size annotation.
我需要的是非常简单:从我的自定义.properties文件中使用我自己的消息,但使用@Size注释提供的参数。
Any suggestions? 有什么建议?
Thank you in advance. 先感谢您。
The proper syntax for accessing the key would be 访问密钥的正确语法是
@Size( min=3, max=5, message="{validator_invalid_state_name}" )
The problem however, is that in the default setup, the key lookup will not be done against your custom.properties, rather against Spring's ValidationMessages.properties. 但问题是,在默认设置中,密钥查找不会针对您的custom.properties进行,而是针对Spring的ValidationMessages.properties。 So the quickest way to get you up & running is to create a ValidationMessages.properties (and the 18n equivalents) and add your keys eg
因此,让您启动并运行的最快方法是创建ValidationMessages.properties(和18n等效项)并添加您的密钥,例如
validator_invalid_state_name=Invalid name ({min}, {max})
That's the simplest solution and no config headaches. 这是最简单的解决方案,没有配置问题。
Now, since you would like this served from you properties file, well, its doable, but you'll have to find a proper configuration. 现在,既然你想从你的属性文件中提供这个,那么,它是可行的,但是你必须找到一个合适的配置。 For Spring 4.x, this would be the proper xml and java config.
对于Spring 4.x,这将是正确的xml和java配置。
Java Config Java配置
@Bean(name = "messageSource")
public MessageSource messageSource()
{
ReloadableResourceBundleMessageSource bean = new ReloadableResourceBundleMessageSource();
bean.setBasename("classpath:text");
bean.setDefaultEncoding("UTF-8");
return bean;
}
@Bean(name = "validator")
public LocalValidatorFactoryBean validator()
{
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource());
return bean;
}
@Override
public Validator getValidator()
{
return validator();
}
XML config XML配置
<annotation-driven validator="validator">
<!--i18n filtering-->
<beans:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<beans:property name="basenames">
<beans:list>
<beans:value>classpath:custom</beans:value>
</beans:list>
</beans:property>
<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>
<beans:bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<beans:property name="validationMessageSource" ref="messageSource"/>
</beans:bean>
For Spring mvc 3.x, you won't find the validationMessageSource property on the LocalValidatorFactoryBean, for that you will have to create you message interpolator, and set it up. 对于Spring mvc 3.x,您将无法在LocalValidatorFactoryBean上找到validationMessageSource属性,因为您必须创建消息插补器并进行设置。 You have an example in this thread http://forum.spring.io/forum/spring-projects/web/78675-jsr-303-validation-spring-mvc-and-messages-properties .
您在此主题http://forum.spring.io/forum/spring-projects/web/78675-jsr-303-validation-spring-mvc-and-messages-properties中有一个示例。 Hope it helps
希望能帮助到你
This solution does not work if you are using Spring Boot with JPA persistence support. 如果您使用具有JPA持久性支持的Spring Boot,则此解决方案不起作用。 The system throws;
系统抛出;
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#427e977': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Post-processing of FactoryBean's singleton object failed; nested exception is java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4f430ea5: startup date [Fri Sep 18 09:33:54 EEST 2015]; root of context hierarchy
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:444)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
... 96 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Post-processing of FactoryBean's singleton object failed; nested exception is java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4f430ea5: startup date [Fri Sep 18 09:33:54 EEST 2015]; root of context hierarchy
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:116)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1523)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:314)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 104 more
Caused by: java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4f430ea5: startup date [Fri Sep 18 09:33:54 EEST 2015]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:344)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.postProcessAfterInitialization(DataSourceInitializedPublisher.java:69)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.postProcessObjectFromFactoryBean(AbstractAutowireCapableBeanFactory.java:1719)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBeanRegistrySupport.java:113)
... 108 more
(What I think is happening is that somehow we loose sight of application.properties where the spring.datasource statements are located, but I have no idea why!). (我认为正在发生的是,我们忽略了spring.datasource语句所在的application.properties,但我不明白为什么!)。 I managed to get this to work with the following java config, dropping the user definition of the messageSource as given by Master Slave above and injecting the SpringBoot provided messageSource.
我设法使用以下java配置工作,删除上面的Master Slave给出的messageSource的用户定义,并注入SpringBoot提供的messageSource。 This now populates my validation messages from messages.properties instead of ValidationMessages.properties
现在,这将从messages.properties而不是ValidationMessages.properties填充我的验证消息
@SpringBootApplication
public class MyApplication extends WebMvcConfigurerAdapter {
@Autowired
MessageSource messageSource;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean(name = "validator")
public LocalValidatorFactoryBean validator()
{
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
bean.setValidationMessageSource(messageSource);
return bean;
}
@Override
public Validator getValidator()
{
return validator();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.