how to configure properties for mvc spring bean controller? - java

Is there a special way for doing this?
What i got is:
config.properties with param.key=value
web.xml with ContextLoaderListener that reads the configuration
pages-servlet.xml that defines servlet beans.
What I want is to configure one of the beans in pages-servlet.xml with param.key.
I'm using <property name="myField" value="${param.key}"/> in the xml but I see that the field is configured with ${param.key} instead of 'value'.
What is the right way to configure the bean?
Ok, I solved it by importing application context file that defines configuration bean into pages-servlet.xml.
It works, but seems very wrong.

Property placeholder is what you want.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:property-placeholder location="classpath:/config.properties" />
<bean id="mybean" class="...">
<property name="xxx" value="${prop.value}" />
</bean>
</beans>

Related

Spring FileSystemXmlApplicationContext getBeanDefinitionNames returns empty array

I have an active profile problem.
Decided to look in debug mode on my context
(profile indepenent contexts works in such way to in my case -
getBeanDefinitionNames returns empty array).
new FileSystemXmlApplicationContext with mentioned file works without exceptions in code fragment mode.
Code
new FileSystemXmlApplicationContext(
"D:\\Projects\\opti\dao\\src\\main\\resources\\contexts\\" +
"\\profiles\\test.xml")
This context with
getBeanDefinitionNames()
returns empty array.
D:\Projects\opti\dao\src\main\resources\contexts\profiles\test.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<beans profile="test">
<context:property-placeholder properties-ref="properties" ignore-resource-not-found="false"/>
<bean id="properties" lazy-init="false"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:properties/test-database.properties</value>
</list>
</property>
</bean>
</beans>
</beans>
Spring 4.2.5
D:\Projects\opti\dao\src\main\resources\properties\test-database.properties
connection.driverClassName=org.hsqldb.jdbc.JDBCDriver
connection.url=jdbc:hsqldb:mem:test
connection.userName=sa
connection.password=
For use beans of a specific profile you should start the jvm with -Dspring.profiles.active=test, or setting spring.profiles.active=test as env variable System.setProperties(props) could be a way for configure it.
I hope that this can help you

Importing Spring bean definition file using relative path

I am writing spring configurations for my project in JAVA. I am new to spring and not to able to figure out the errors related to spring.
I have the following file structure:
ProjectName
--> src
--> META-INF
--> jobs
-->edx
-->request-details.xml
-->clients.xml
-->daos.xml
-->environment.xml
--> request-details-edx-upload.xml
In META-INF/request-details-edx-upload.xml I import the following:
<import resource="jobs/environment.xml" />
<import resource="classpath:META-INF/jobs/edx/request-details.xml" />
<import resource="jobs/clients.xml" />
<import resource="jobs/daos.xml" />
But I get the following error:
Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:META-INF/jobs/edx/request-details.xml]
Offending resource: class path resource [META-INF/request-details-edx-upload.xml]; nested exception is org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionDecorator for attribute [dataSetName]
Offending resource: class path resource [META-INF/jobs/edx/request-details.xml]
request-details.xml is something like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
">
<!-- RequestDetails EDX data upload dao -->
<bean id="requestDetailsDataUploadDao" class="com.amazon.edx.dao.DataUploadDaoEdxClientImpl"
context:providerName="scot"
context:subjectName="${edxRequestDetailsSubject}"
context:dataSetName="by-01-day"
context:keyName="${regionValue}"
context:edxClient-ref="edxClient"
/>
<util:list id="requestDetailsColumnMetaData" value-type="com.amazon.edx.transformer.ColumnMetaData">
<ref bean="Column"/>
<ref bean="Column1"/>
</util:list>
<bean id="Column" class="com.amazon.edx.transformer.ColumnMetaData"
context:attributeName="Id"
context:dataType="VARCHAR2"
context:columnDisplayName="IMS"
/>
<bean id="Column1" class="com.amazon.edx.transformer.ColumnMetaData"
context:attributeName="id1"
context:dataType="VARCHAR2"
context:columnDisplayName="IMS"
/>
<util:constant id="tabDelimiter"
static-field="com.amazon.edx.transformer.Delimiters.TAB_DELIMITER" />
<!-- RequestDetails data backup -->
<bean id="requestDetailsDataTransformer" class="com.amazon.edx.transformer.DataTransformerImpl"
context:dataFlattener-ref="requestDetailsDataFlattener"
context:columnMetadata-ref="requestDetailsColumnMetaData"
context:delimiter="{tabDelimiter}"
/>
</beans>
Is there anything obvious I'm doing wrong with my import of the relative path?
Thanks.
Seems it is wrong schema definition. Try to remove namspace xmlns:context="http://www.springframework.org/schema/context" from <beans> tag. Instead add xmlns:p="http://www.springframework.org/schema/p" namespace. Also you should replace all context: suffix with p: suffix. Proper xml using shortcut with the p-namespace should looks like following:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<!-- RequestDetails EDX data upload dao -->
<bean id="requestDetailsDataUploadDao" class="com.amazon.edx.dao.DataUploadDaoEdxClientImpl"
p:providerName="scot"
p:subjectName="${edxRequestDetailsSubject}"
p:dataSetName="by-01-day"
p:keyName="${regionValue}"
p:edxClient-ref="edxClient"
/>
....
</beans>

Error loading messages from .properties file

I'm trying to have my project's Strings/ messages stored in an external .properties file. I think I have everything wired up OK, but still I get:
org.springframework.context.NoSuchMessageException: No message found under code 'subtype.user.client' for locale 'null'.
Whenever I try:
String string = messageSource.getMessage("subtype.user.client", null, null);
My spring xml config files are as follows. Since the project is really big with lots of beans, I have different spring xml config files defining different types of beans, and a main spring.config.xml file that wires them all together.
Messages file named messages.subtypes
subtype.user.user=User
subtype.user.client=Client props
subtype.user.staff=Staff
subtype.user.clerk=Clerk
subtype.user.secretary=Secretary
Messages beans file called spring.messages.config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename">
<list>
<value>messages.subtypes</value>
</list>
</property>
</bean>
<bean id="myProjectLangs" class="myprojectbase.MyProjectLangs">
<property name="messageSource" ref="messageSource"></property>
</bean>
</beans>
The main spring.config.xml config file that wires all the beans together via <import resource="classpath:filename.xml"/>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<aop:aspectj-autoproxy />
<import resource="classpath:spring.messages.config.xml"/>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource" />
<context:annotation-config />
<context:component-scan base-package="myprojectbase"/>
</beans>
You get this error because you pass the Locale parameter as null. Try
String string = messageSource.getMessage("subtype.user.client", null, Locale.ENGLISH);
Even though you have not defined a file messages.subtypes_en.properties defined it should fall back to messages.subtypes.properties
A couple of things come to mind looking at your code any of which might cause the problem:
Your xml config name contains "." as separators. This is against conventions. Consider renaming your config file to spring-messages-config.xml
Your language properties file has no properties suffix, again convention suggests to name this file messages-subtypes.properties
In both your application context xml files you define a bean named messageSource. Consider deleting one of them.
My prime suspicion as to why your code does not work lies with the way you define basename on ReloadableResourceBundleMessageSource. Looking at the JavaDoc for setBasename method there is some form of convention of configuration at work:
Set a single basename, following the basic ResourceBundle convention of not specifying file extension or language codes, but in contrast to {#link ResourceBundleMessageSource} referring to a Spring resource location: e.g. "WEB-INF/messages" for "WEB-INF/messages.properties", "WEB-INF/messages_en.properties", etc. XML properties files are also supported: .g. "WEB-INF/messages" will find and load "WEB-INF/messages.xml", "WEB-INF/messages_en.xml", etc as well.
This suggests that once you have renamed your message properties file to messages-subtypes.properties, you should change your config to <value>classpath:messages-subtypes</value>, make sure that the file is in the classpath and everything should start working.
Try renaming the messages.subtypes file to messages.subtypes.properties.

Error while applying session scope to a bean in spring

I tried to change the scope of a bean using #Scope annotation. That bean is actually working as MessageSource and used for internationalization purpose.
The schema in mvc-dispacher-servlet.xml is as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
Exception described in console is as follows:
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Cannot locate BeanDefinitionParser for element [scoped-proxy]
Ok. If its a normal bean then most likely you are just missing the xml parser for the scope tag. To be able to use scoped proxies you need to register aop:scoped-proxy.
There is a similar question on SO:
Accessing a session-scoped bean inside a controller
Which results in:
http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes-other-injection
Else you should easily find some tutorials on this topic through google.
It is likely that you have a bean-scoped option outside the bean (I made such mistake and got an error msg like yours) :
<beans>
...
<aop:config proxy-target-class="true"/>
<aop:scoped-proxy proxy-target-class="true"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>
...
Just put that option inside of the bean declaration:
<bean ... target="step">
<aop:scoped-proxy proxy-target-class="true"/>
</bean>
One more thing - I got such error only for scoped beans.

Why is the ${} variable not interpreted as a constructor-arg value, in my context file?

I have a Spring 3.1 application, and I try to use a system variable in the context files. The variable "JAVA_MY_ENV" is defined on my System (on Windows, it is in the "System variables", from the control panel).
In web.xml, I can use it as a variable and it works, it is successfully replaced by the actual value of the variable (let's say "electrotype") :
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log/${JAVA_MY_ENV}.log4j.properties</param-value>
</context-param>
I can also use it in my main "bean" context, to do an import, and it also works :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!-- (...) -->
<import resource="classpath:spring/app-config.xml" />
<import resource="classpath:spring/env/context-env-${JAVA_MY_ENV}.xml" />
</beans>
But In "app-config.xml", one of my other context file, I try this and it doesn't work :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="appConfiguration" class="com.xxx.app.AppConfiguration">
<constructor-arg value="${JAVA_MY_ENV}" />
</bean>
</beans>
The com.xxx.app.AppConfiguration receives the String "${JAVA_MY_ENV}" as the constructor parameter, not the interpreted value of it!
I'm not sure to understand where the ${} variables are interpreted and where they are not.
Is there a way I can pass the interpreted ${JAVA_MY_ENV} value to my com.xxx.app.AppConfiguration constructor?
As of 3.0 in Spring you should be to inject values into properties
#Value("#{ systemProperties['JAVA_MY_ENV'] }")
private String myVar;
or
<property name ="myVar" value="#{systemProperties['JAVA_MY_ENV']}"/>
Alternatively you can look into using the PropertySourcesPlaceholderConfigurer or similar class. Creating this will tell spring how to look for variables. Often i make a number of property files as well so that environment and internal property file values are available to the app. e.g.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:someprops.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
<property name="searchSystemEnvironment" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
A key element in the above example is the "searchSystemEnvironment" being set to true. This tells spring to use env variables (which is what you want)
Possible duplicate of <context:property-placeholder> properties not accessible to the child (web) context
As I understand this is expected behavior. You should inject beans only in servlet context or to include configuration bean into servlet-context.xml
To use a PropertyPlaceholderConfigurer, suggested by BruceLowe, works. Another way (maybe more complicated) I found to resolve a specific property is using :
<bean id="JAVA_MY_ENV" class="org.springframework.util.SystemPropertyUtils" factory-method="resolvePlaceholders">
<constructor-arg value="${JAVA_MY_ENV}" />
</bean>
This creates a String bean containing the resolved value of ${JAVA_MY_ENV}!
Then I can use this bean anywhere a bean ref can be used. For example as a constructor-arg:
<bean id="appConfiguration" class="com.xxx.app.AppConfiguration">
<constructor-arg ref="JAVA_MY_ENV" />
</bean>
So now I use ${JAVA_MY_ENV} in places where it is interpreted, without adding PropertyPlaceholderConfigurer, and the JAVA_MY_ENV bean otherwise.

Categories

Resources