Bind values in property file dynamically using Spring - spring

In my web application i have a scenario like i need to read the values from property file and the value has to be updated dynamically in spring bean. I have created the key value pair as follows,
message1=Hi {0} welcome. Your last signed in was {1}
How to substitute the values for {0} and {1}. I have read the value using property place holder configurer in spring.

You have to do it with MessageSource
In your applicationContext add:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>messages</value>
</list>
</property>
</bean>
In your javacode you can write:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//...
String name = context.getMessage("message1", new Object[] { "user XY", "05.05.2010" }, Locale.US);
You even can use different message.properties files for different languages: Then you have to name these files: [filename]_[languageCode] (i.e. messages_en_US.properties or messages_de_DE.properties). And change your 3rd parameter of the getMessage method.

Related

How to initialize a bean basis on propertiy file boolean key value pair

I am new to spring, Is there any way to initialize spring bean using property file key-value pair;
; if like my config.properties file contains isSetup = true;
then only initialize, <bean id="a" class="com.Setup"/>
Please refer this post
How can I inject a property value into a Spring Bean which was configured using annotations?
This link can also help you : http://springinpractice.com/2008/12/02/new-stuff-in-spring-30/
You can pass the property as below to bean :
<bean id="a" class="com.Setup"/>
<property name="isSetup " value="#{systemProperties.isSetup }"/>
</bean>

How to use MappingJackson2HttpMessageConverter to convert Maps and List correctly?

In my Spring MVC project MappingJackson2HttpMessageConverter configured as follows:
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter" />
</list>
</property>
</bean>
For plain simple Java POJO Beans, serialization works well. All good. But, i also have Beans that include Maps that needed to be serialized as well, and it's fails (JsonMappingException).
From Jackson instructions, I know that to solve this what needed is to indicate the actual type for the object mapper. It looks like that:
Map<String, ResultValue> results = mapper.readValue(jsonSource,
new TypeReference<Map<String, ResultValue>>() { } );
How can be the same configuration be done to MappingJackson2HttpMessageConverter (with based on Jackson2 object mapper)?
It's not clear from your question what doesn't work, but I'm guessing that you have a bean that contains java.util.Map or java.util.List property and you're getting com.fasterxml.jackson.databind.JsonMappingException when deserializing that bean.
In that case you can give hints on fields with #JsonDeserialize annotation. So for instance if you have a java.util.Map<String, ResultValue> field, you can annotate it like:
#JsonDeserialize(keyAs = String.class, contentAs = ResultValue.class)
public Map<String, ResultValue> map;

How to inject complete propertiesfile in a springbean

I have a properties-file with a lot of values and I do not want to list them in my bean-configuration-file separately. E.g.:
<property name="foo">
<value>${foo}</value>
</property>
<property name="bar">
<value>${bar}</value>
</property>
and so on.
I imagine to inject all completely as java.util.Properties or less as a java.util.Map.
Is there a way to do so?
For Java config you can use something like this:
#Autowired #Qualifier("myProperties")
private Properties myProps;
#Bean(name="myProperties")
public Properties getMyProperties() throws IOException {
return PropertiesLoaderUtils.loadProperties(
new ClassPathResource("/myProperties.properties"));
}
You can also have multiple properties this way, if you assign a unique bean name (Qualifier) to each instance.
Yes, you can use <util:properties> to load a properties file and declare the resulting java.util.Properties object as a bean. You can then inject that as you would any other bean property.
See section C.2.2.3 of the Spring manual, and their example:
<util:properties id="myProps" location="classpath:com/foo/jdbc-production.properties"
Remember to declare the util: namespace as per these instructions.
For Java Config, use PropertiesFactoryBean:
#Bean
public Properties myProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/myProperties.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
log.warn("Cannot load properties file.");
}
return properties;
}
And then, set the properties object:
#Bean
public AnotherBean myBean() {
AnotherBean myBean = new AnotherBean();
...
myBean.setProperties(myProperties());
...
}
Hope this helps for those interested in Java Config way.
It's possible with the PropertyOverrideConfigurer mechanism:
<context:property-override location="classpath:override.properties"/>
Properties file:
beanname1.foo=foovalue
beanname2.bar.baz=bazvalue
The mechanism is explained in the section 3.8.2.2 Example: the PropertyOverrideConfigurer
This is an echo of #skaffman's response in this SO question. I am adding more details to help others and myself when I try to solve this in the future.
There are three ways to inject the property file
Method 1
<bean id="myProps" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:com/foo/jdbc-production.properties</value>
</list>
</property>
</bean>
Reference ( link )
Method 2
<?xml version="1.0" encoding="UTF-8"?>
<beans
...
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="...
...
http://www.springframework.org/schema/util/spring-util.xsd"/>
<util:properties id="myProps" location="classpath:com/foo/jdbc-production.properties"/>
Reference ( link )
Method 3
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:com/foo/jdbc-production.properties" />
</bean>
Reference ( link )
Essentially, all the methods can create a Properties bean out of the properties file. You may even directly inject a value from the property file by using #Value injector
#Value("#{myProps[myPropName]}")
private String myField;

Reading valued from properties file at Runtime

I want to get specific value based on request from the property file.how to do that?
I have following spring configuration.i want to set the value for Exprops as per the request and get corresponding values from the properties file
<bean id="Prop" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:ErrorMessage.properties</value>
</property>
</bean>
<bean id="PropertiesBean" class="com.util.PropertiesUtil">
<property name="Exprops" value="${EXampleExceptiion}"></property>
</bean>
Use the PropertiesFactoryBean to inject the Properties in a Bean.
<bean id="myPropertiesBean"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:ErrorMessage.properties"/>
</bean>
This provides a Properties Object/Bean which can be injected under the name myPropertiesBean in any Bean (<property name="x" ref="myPropertiesBean"/>).
In addition Spring provides the util namespace (since Spring 2.5):
There you can write the PropertyFactoryBean definition a bit shorter:
<util:properties id="myPropertiesBean"
location="classpath:ErrorMessage.properties"/>
#see Spring Reference Chapter C.2.2.3.
All use the following for doing this programmatically
XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
cfg.postProcessBeanFactory(factory);
<util:properties id="" location="location of prop file" />
this return java.util.Properties object

Hibernate Validation and localized error messages?

hibernate and i want to provide localized error messages for hibernate annotations
so i created to properties files ValidatorMessages.properties, ValidatorMessages_ar.properties
and put them in resources folder, and i am using messageSource to read from property files:
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages</value>
<value>classpath:errors</value>
<value>classpath:app</value>
<value>classpath:ValidatorMessages</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8" />
</bean>
and in the class i use something like:
#NotNull(message = "{validation.notEmpty.password}")
private string password;
and when calling the validator i use:
Validator validator = Validation.buildDefaultValidatorFactory()
.getValidator();
Set<ConstraintViolation<MyClass> cvs = validator
.validate(myObject);
for (ConstraintViolation<MyClass> cv : cvs) {
String field = cv.getPropertyPath().toString();
result.addError(new FieldError("version", field, cv.getMessage()));
}
if (result.hasErrors()) {
initModel();
result.reject("add.version.errors");
return "manageVersions";
}
it works fine with english, it displays english messages correctly, but when switching to arabic it still displays the english messages instead of arabic, although that
LocaleContextHolder.getLocale() indicates that the language is changed and it's arabic, so is there are something missing with the configuration or any ideas what might cause that ?
In your Spring config when you are setting up your validator bean, I think you need to set the message interpolator:
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator" ref="interpolator" />
</bean>
where the interpolator bean would be of type LocaleContextMessageInterpolator (see here for more info). Hibernate Validator doesn't automatically know to look at LocaleContextHolder.
You might also need to set validationMessageSource property but I think its defaulted properly since you are at least getting the English error messages.

Resources