Can I define two property files using ResourceBundleMessageSource like:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>com/app/view/web/AppResource1</value>
<value>com/app/view/web/AppResource2</value>
</list>
</property>
</bean>
If that is possible with ResourceBundleMessageSource, How to use both the property files in Bean file. Till now, I am using only one property file in any bean by injecting messageSource in to it and using like:
public class BeanOne {
public BeanOne(ResourceBundleMessageSource bundleMessageSource) {
this.messageSource = bundleMessageSource;
}
....
this.messageSource.getMessage("",locale);
}
Please tell me how to access both property files in a bean. Thanks.
The properties from both files are included in the message source.
If you have com/app/view/web/AppResource1:
com.app.view.web.propertyA=foo
And com/app/view/web/AppResource2:
com.app.view.web.propertyB=bar
Then in your bean, you access can them:
messageSource.getMessage("com.app.view.web.propertyA", LOCALE); // foo
messageSource.getMessage("com.app.view.web.propertyB", LOCALE); // bar
Related
I want to externalize application message to properties file. I'm loading the properties file using Spring.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:applicationmessage.properties</value>
</list>
</property>
<property name="ignoreResourceNotFound" value="true" />
I have the message with para
message.myMessage = Couldn't find resource for customer id {0} and business unit {1}
What's the best way to read this message with parameter from java file ? Is there any other approach to externalize the messages.
It depends, exists differents ways to do, directly in jsp, in form validation process, etc..
For example
Message in properties:
msg=My message {0} and {1}.
In your jsp:
<spring:message code="msg"
arguments="${value1},${value2}"
htmlEscape="false"/>
http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/spring.tld.html#spring.tld.message
hi there are several ways to get properties message from spring.
way 1:
<util:properties id="Properties" location="classpath:config/taobaoConfig.properties" />
add this in spring.xml
in your java file . you create following property.
#Resource(name = "Properties")
private Properties serverProperties;
the key-value in properties file will in serverProperties property.
way 2:
create a properties container bean
<bean id="propertyUtil" class="com.PropertiesUtil">
<property name="locations">
<list>
<value>/WEB-INF/classes/datasource.properties</value>
<value>/WEB-INF/classes/fileDef.properties</value>
</list>
</property>
</bean>
code of com.PropertiesUtil
public class PropertiesUtil extends PropertyPlaceholderConfigurer {
private Properties properties;
#Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) {
super.processProperties(beanFactory, props);
this.properties = props;
}
/**
* Get property from properties file.
* #param name property name
* #return property value
*/
public String getProperty(final String name) {
return properties.getProperty(name);
}
}
you can use this container bean to get key-value in properties files .
I have implemented a bean with hibernate and hibernate validation. This is the field I am testing on.
#NotBlank(message ="test.test" )
private String test;
I have a file
messages.properties
and
messages_en.properties
that I use. Spring.message tags work so the files can be found and are used in the system elsewhere. I get "test.test" as my validation error when I try to store an object with that field empty and not error message in messages.properties. What am I missing?
You should try like this by enclosing key name with curly braces. This syntax is different than Java from the localization files. It's followed with Spring/Hibernate Validation thru Validation API.
#NotBlank(message="{test.test}")
private String test;
The problem was that i was missing this in my configuration. Also message="{test.test}" was necessary.
<mvc:annotation-driven validator="validator" />
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator">
<bean class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator">
<constructor-arg index="0">
<bean
class="org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator">
<constructor-arg index="0" ref="messageSource" />
</bean>
</constructor-arg>
</bean>
</property>
</bean>
Only below worked for me:
Create ValidationMessages.properties in "resources" directory of maven project with the below message property:
app.validation.notempty.msg=must be populated
Then, in dto class:
#NotEmpty(message = "{app.validation.notempty.msg}")
private String fieldName;
Fially validate as shown below. Please note I found provider HibernateValidator.class is mandatory to take the values from .properties file.
ValidatorFactory factory = Validation.byProvider(
HibernateValidator.class )
.configure()
.buildValidatorFactory();
Validator validator = factory.getValidator();
Hope this helps someone.
I'm using glassfish 3.1, spring 3.2 and jdk 1.7.
I have configured two custom JNDI resources in Glassfish. One is called 'config' and the other is called 'mappings'. But when I reference one of them in the code, it actually has the properties for both and all system properties (catalina.base etc). I only want the one, not all 3 sets.
I have it set so I get the properties in the spring context file:
<jee:jndi-lookup id="mappingsJndi" jndi-name="mappings" resource-ref="true" />
<bean id="propertyMappings" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="propertiesArray">
<list>
<ref bean="mappingsJndi"/>
</list>
</property>
</bean>
I reference it in the servlet. It's injected like this:
#Autowired
Properties[] propertyMappings;
The injection works, but it contains 3 properties objects instead of the one. Is there any way around this?
Looks like I figured it out. Instead of referencing the propertyMappings bean like this:
#Autowired
Properties[] propertyMappings;
I just reference the JNDI lookup directly:
#Autowired
Properties mappingsJndi;
First: I'm using Spring 3.0
I have a problem when configuring my controller class. The controller uses a web service which I want to define the endpoint address using a .properties file.
#Controller
public class SupportController {
#Value("#{url.webservice}")
private String wsEndpoint;
...
In my application context xml-file, I've defined this:
<context:property-placeholder location="/WEB-INF/*.properties" />
I've been reading the documentation, trying different approaches (like adding prefix systemProperties.),but I keep getting an error message telling me that it doesn't exist.
Field or property 'url' cannot be
found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'
Ok. I've figured it out.
Now, in the controller:
#Value("#{settings['url.webservice']")
Then in the context configuration I have this "helper bean":
<util:properties id="settings"
location="/WEB-INF/supportweb.properties"></util:properties>
This should work, too:
#Value("${url.webservice}")
private String wsEndpoint;
I have this configuration and it works fine:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
</bean>
and I iniejct the property in this way
#Value("${root.log.level}")
private String prop;
the field is correctly initialized to "DEBUG" value.
you should check that the
<context:property-placeholder location="/WEB-INF/*.properties" />
is defined in webmvc-config.xml where you create instances of the #Controllers
our project is based on Spring IoC which provides easy extensibility, meaning the functionality of our project is extended by what we call extensions (or plug-ins) that provide a few additional Spring xml configuration files + new code.
The problem is I have to somehow distinguish between beans that have been loaded from different xml files.
Example: two extensions (let's call them A and B) installed two additional spring files: A.xml and B.xml. Both these files define beans of the same Java class. The framework loads all beans of this class (using autowiring) to some factory and later uses this list of beans in specific algorithms. But it should be able to know that what extension a bean is defined by.
Of course I can add an additional required property (for example name or code of the extension) for the beans and then extensions developers will have to fill it for every bean definition, but this is error prone: the property should be the same for all the beans of some particular extension, while it is filled for every bean. I'm looking for a more elegant solution that is less verbose.
Thanks.
It sounds like each of your extensions should be defined within its own application context. Each of these contexts would share a single parent context, which would be your application "core".
This shoulkd give you an easier way of knowing which bean came from what, since you'd have to go through each context to obtain the beans to start with. Also, by isolating each extension in its own context, you reduce the possibility of beans clashing.
Configure each extension in a separate application context. In each application context, define a BeanPostProcessor which saves every bean the application context defines to a registry that maps beans to application contexts.
Configure an application context which will be the parent for each extension application context. In this configuration file, define a bean which maps bean names to application context identifiers.
<!-- parent.xml -->
<beans>
<bean
id="beanNameToApplicationContextIdMap"
class="java.util.HashMap"/>
</beans>
The extension application context configuration file defines an instance of BeanNameToApplicationContextIdMapInserter, which is a custom class implementing the BeanPostProcessor interface. The applicationContextId property is configured to a string identifying the application context. The map property configures the instance to update the map defined in the parent application context.
<!-- alpha.xml -->
<beans>
<bean class="com.example.BeanNameToApplicationContextIdMapInserter">
<property name="applicationContextId" value="alpha"/>
<property name="map" ref="beanNameToApplicationContextIdMap"/>
</bean>
<bean id="alphaService" class="...">
</bean>
</beans>
The BeanNameToApplicationContextIdMapInserter source code:
public class BeanNameToApplicationContextIdMapInserter implements BeanPostProcessor {
private String applicationContextId;
private HashMap<String, String> map;
public void setApplicationContextId(String id) {
this.applicationContextId = id;
}
public void setMap(HashMap<String, String> map) {
this.map = map;
}
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException
{
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
{
map.put(beanName, applicationContextId);
return bean;
}
}
You can use SingletonBeanFactoryLocator to configure the parent application context and each extension application context.
<!-- beanRefFactory.xml -->
<beans>
<bean
id="parentApplicationContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<value>parent.xml</value>
</constructor-arg>
</bean>
<bean
id="alphaApplicationContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<value>alpha.xml</value>
</constructor-arg>
<constructor-arg>
<ref bean="parentApplicationContext"/>
</constructor-arg>
</bean>
<bean
id="bravoApplicationContext"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<value>bravo.xml</value>
</constructor-arg>
<constructor-arg>
<ref bean="parentApplicationContext"/>
</constructor-arg>
</bean>
</beans>
Here is example code that reads the bean to application context map.
public class Main {
private static ApplicationContext getApplicationContext(String name) {
BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance();
BeanFactoryReference bfr = bfl.useBeanFactory(name);
return (ApplicationContext) bfr.getFactory();
}
public static void main(String[] args) {
ApplicationContext parentApplicationContext =
getApplicationContext("parentApplicationContext");
HashMap<String, String> map = (HashMap<String, String>)
parentApplicationContext.getBean("beanNameToApplicationContextIdMap");
System.out.println(map.get("alphaService"));
System.out.println(map.get("bravoService"));
}
}