Loading properties from a file AND system properties using Spring - spring

Searched through some other posts but could not find exactly what I needed, but I would guess this is an easy question..
So I have a property file called myprops.properties
myprops.localProp1=localProp1
myprops.localProp2=localProp2
myprops.systemProp=${systemPropertyName}
Basically, in this property file I want to use the values as is for localProp1 and locapProp2 but for systemProp, I would like to load the system property. Let's assume that the system property is always set.
My spring config xml looks like this...
<bean id="myprops" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<qualifer value="myprops" />
<property name="singleton" value="true"/>
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list><value>classpath:myprops.properties</value></list>
</property>
</bean>
I use the qualifier have this bean autowired and use the qualifier string "myprops" to access it in another class. All the expected values are there except the myprops.systemProp, it still = ${systemPropertyName}.
How would I get this property to be resolved with the actual system property?
I tried the following in my spring config:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="myprops" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
</bean>
This didn't seem to help..
Any ideas? I'm hoping this is an easy one and I am just misunderstanding a common concept in property configuration.
Note: I had to manually type all the code couldn't copy/paste so please excuse typos.
Thanks.

Related

spring-batch : load and use a property file

I am new on Spring batch so am here to ask some basic advice.
What is the best approach to load a config file in memory (or bean) and use its content while the spring Job/step are running ?
I am not sure but based on some google search I found the below scenario even if I dont quite understand why I should define a writer even if i dont need it :
step1 : load config file (the content is two field delimited by =)
step2 : perform some java code and use the previous config file
so for the step 1 :
<bean id="inputFile" class="org.springframework.core.io.FileSystemResource" scope="step">
<constructor-arg value="path_config_file"/>
</bean>
<bean id="readerConfigFile" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
<property name="resource" ref="inputFile"/>
<property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="field,value"/>
<property name="delimiter" value="="/>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="prototypeBeanName" value="configProperties"/>
</bean>
</property>
</bean>
</property>
</bean>
<bean id="outputConfig" class="outputConfig"></bean>
<bean id="configProperties" class="configProperties" scope="prototype"/>
so my question are :
How can I use the information gathered in the file ? Should I put them in the Java bean ?
How can I pas this info between different step or make them persistent in the whole application life-cycle ?
Would you recommend to use a itemProcessor to achieve the above ?
Any advice are most than welcome
I'm a bit confused about your questions because I think you only need to load a properties file in spring context using a PropertiesFactoryBean:
<bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location">
<value>file:path_config_file</value>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="propertiesArray">
<list>
<ref bean="config"/>
</list>
</property>
</bean>
and you can refer to property values using ${} placeholder; but this solution is unrelated to spring-batch; I don't need it!
About your questions:
Using a POJO is a good way because spring-batch offers in-box mapping strategies (BeanWrapperFieldSetMapper in your case)
Objects used in a job are accessible only in job context, not in application context (this is why I think you need a PropertiesFactoryBean).To pass object between steps read How can we share data between the different steps of a Job in Spring Batch?
ItemProcessor is requested if you need to convert an object T read from a ItemReader<T> to an object of type S written by an ItemWriter<S>. So no, you don't need an ItemProcessor.
I hope I was clear, English is not my native language

Jaxb2Marshaller xsd schema validation query

I am using spring 3.0.6 Jaxb2Marshaller using below configuration,
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPaths">
<list>
<value>com.xxx.yyy.schema.external_request.event</value>
<value>com.xxx.yyy.schema.zzz.external_request</value>
</list>
</property>
</bean>
I want to validate xml against against the external_request.xsd which it is not doing. Do I need to explicitly pass the schema property even if the generated sources have the annotation which mentions that element is required something like #XmlElement(name = "abc", required = true). Has any one already faced this issue. Thanks!
Hey may be instead of adding classes to context paths you can try adding it to classesToBeBound proprty
<bean id="jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.xxx.yyy.schema.external_request.event</value>
<value>com.xxx.yyy.schema.zzz.external_request</value>
</list>
</property>
</bean>
Please rate the answer if it helps.
cheers

Register a custom conversion service while retaining the defaults?

In a spring-mvc 3.2.RELEASE project I'd like to use org.springframework.data.repository.support.DomainClassConverter to easily get me entities injected.
It works fine when using this config:
<beans:bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" />
<beans:bean id="conversionService"
class="org.springframework.core.convert.support.DefaultConversionService" />
<beans:bean
class="org.springframework.data.repository.support.DomainClassConverter">
<beans:constructor-arg ref="conversionService" />
</beans:bean>
<annotation-driven conversion-service="conversionService" />
But then Spring isn't loading the formatter for dealing with Joda time types and i get "Failed to convert property value of type java.lang.String to required type org.joda.time.LocalDate for property"
Using only
<annotation-driven/>
The Joda conversion works but not the entity injection.
How do you wire it upp so both work?
Not sure if this answers the question, but I came across a similar problem and this is how I resolved it.
I had implemented a custom converter and conversion service using the documentation
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="example.MyCustomConverter"/>
</list>
</property>
</bean>
The result was what #NA described - this loses the default joda time support and the following definition in an unrelated controller no longer works
#PathVariable(value="day") #DateTimeFormat(pattern=DATE_FORMAT) LocalDate date
The solutions was instead of using org.springframework.context.support.ConversionServiceFactoryBean, I began using org.springframework.format.support.FormattingConversionServiceFactoryBean.

Autowire HttpServletRequest? To solve Locale?

My current project requires a customized "System date", which means a system date and it's format defined in the i18n properties file. But the class dealing with it is a general utility class but not within the web layer. However the locale(to work out the date format) has to be retrieved from a HttpServletRequest object. I am thinking autowire a HttpServletRequest instance to that utility class. It seems break the design pattern but I guess it is piratical. However it doesn't work. So what is wrong with that and is there any better way to solve the Locale in any other layers in Spring?
Thanks in advance.
Wouldn't it be a lot more elegant to simply overload the utility-class to accept a Locale as parameter on the affected methods. Then you can retrieve the locale in your controller and pass it down to the utility.
I prefer you to use the Spring Framework's SessionLocaleResolver. It will change and store the locale in the session and hence you can get that at any point of code in the application.
Please refer the below mentioned configuration for the same. And also read the Spring Documentation for the same for the better understanding.
<mvc:interceptors>
<ref bean="localeChangeInterceptor"/>
</mvc:interceptors>
<bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="lang"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="en"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>/WEB-INF/i18n/labels</value>
<value>/WEB-INF/i18n/messages</value>
</list>
</property>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
Hope this helps you. Cheers.

Spring PropertiesFactoryBean that automatically exposes a PropertyPlaceholderConfigurer's property

Ideally I'd like to do this from code:
#Value("#{aPropertiesFactoryBean.aProperty}")
private String aProperty;
Based on a spring configuration where I set up a PropertyPlaceholderConfigurer and a PropertiesFactoryBean, and just pass the configurer bean as a ref to the bean, and everything that the configurer generates is exposed as a property of the factory bean.
There is a hack to just redefine every property from the Configurer like:
<bean id="aPropertiesFactoryBean"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="properties">
<props>
<prop key="aProperty">${aProperty}</prop>
</props>
</property>
</bean>
And then every time you add a property to the Configurer, you have to re-expose it with the FactoryBean. And the punchline is, I want all the management features of the configurer, and also be able to reference the same batch of properties from both the spring xml files, and #Value annotations.
So the two questions:
Is there something like this out of the box?
It looks like it would be simple to override PropertiesFactoryBean and give it a property for the PlaceholderConfigurer, but the code to actually access the properties would have to involve unwelding the hood through reflection and digging into Spring's internal PropertiesLoaderSupport class. Is there a less hacky way to do this?
Note, I'm not looking for something that can just quickly get me on my way, the above hack with PropertiesFactoryBean suffices for now. I'm looking to either find or make a reusable component that I can use to easily manage injectable properties for projects down the road.
I was just thinking about this backwards. This config does exactly what I want, being able to have properties defined in the xml config, overridable from a properties file, and available as both placeholder properties and injectable values.
<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/spring-beans-3.0.xsd">
<!--
One-stop shopping for properties here.
Available as injected values and elsewhere in the spring config.
-->
<bean id="injectableProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="properties">
<props>
<prop key="prop1">value1</prop>
<prop key="prop2">value2</prop>
</props>
</property>
<!-- Allow foo.conf to override default properties -->
<property name="location" value="file:/etc/foo/foo.conf" />
</bean>
<!-- Expose the properties so other parts of the spring config can use them -->
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="false" />
<property name="properties" ref="injectableProperties"/>
</bean>
</beans>
Maybe I'm misunderstanding the situation, but you can inject properties without having to define a PropertiesFactoryBean by using the syntax:
#Value("${my.property}") String myProperty;

Resources