简体   繁体   English

如何使用我的.properties文件中的自定义消息,但使用@Size注释提供的参数?

[英]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.

相关问题 无法使用spring-mvc使用大小注释从属性文件中打印消息 - Not able to print message from properties file using size annotation using spring-mvc 如何在Spring中使用注释验证并从属性文件中获取错误消息? - How to use annotation validation in Spring with error message gotten from properties file? 如果使用@Value注释从属性文件注入参数,如何调用函数 - How to call a function if it's parameters are injected from properties file using @Value annotation 如何在属性文件的@Size注释中设置最大值? - How to set max value in @Size annotation from properties file? 如何从属性文件导入值并在注释中使用它? - How to import value from properties file and use it in annotation? 使用RestEasy,如何在传入对象参数之一的属性上使用@HeaderParam批注? - Using RestEasy, how can I use a @HeaderParam annotation on the properties of one of the incoming object parameters? 如何使用@Named批注从Spring 3.0的属性中注入构造函数参数? - How to inject constructor parameters from properties in Spring 3.0 with the @Named annotation? 从自定义注释中读取属性 - read properties from custom annotation Java:如何使用Spring注释将.properties文件的内容加载到Properties中? - Java : How to load content of .properties file into Properties using spring annotation? Thymeleaf:如何在JSR-303注释中使用自定义消息密钥 - Thymeleaf : How to use Custom Message Key in JSR-303 Annotation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM