MessageSource and PropertyPlaceholderConfigurer cannot load messages but with classpath*
My applicationContext.xml is in path:
src/main/resources/META-INF/spring
and property files are in path:
src/main/resources/messages
and I load spring context in web.xml as follows:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:META-INF/spring/applicationContext.xml</param-value>
</context-param>
when I am configuring MessageSource and PropertyPlaceholderConfigurer
as follows:
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:messages/apps.properties</value>
</list>
</property>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:messages/ValidationMessages</value>
<value>classpath:messages/app</value>
</list>
</proper开发者_C百科ty>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
they both don't work, it only works when I change classpath
to classpath*
Any ideas why?
From Spring documentation:
4.7.2.2 The classpath*: prefix
[...] location string may use the special
classpath*:
prefix: [...]This special prefix specifies that all classpath resources that match the given name must be obtained [...], and then merged to form the final application context definition.
Are you sure there are no other messages/apps.properties
files on your CLASSPATH coincidentally taking precedence and overriding your file? This description suggests that you might have several same named files that are merged when *
is used.
Can you check this by calling:
SomeClass.class.getClassLoader().getResources("/messages/apps.properties");
?
Look at this excellent article for classpath v classpth* difference in regards to spring resource loading, I did some testing on your problem in my testing it worked whether i used classpath or classpath*
I am listing the code here about the test i did
- I created a this directory structure (META-INF/spring under src/main/resource) placed context.xml
I am listing complete context.xml here
<?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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:messages/apps.properties</value> </list> </property> </bean> <bean class="prasanna.service.TestBean"> <property name="appName" value="${appname}"></property> </bean> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:messages/ValidationMessages</value> <value>classpath:messages/apps</value> </list> </property> <property name="defaultEncoding" value="UTF-8"/> </bean> </beans>
Listing for apps.properties
appname=spring mvc app
Listing for ValidationMessages.properties
error.name=Invalid name
TestBean is rather simple
public class TestBean { private String appName; public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } }
I am using a simple java class to load the property files and read them
public class LoadContext { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:META-INF/spring/context.xml"}); ReloadableResourceBundleMessageSource msgs = ctx.getBean(ReloadableResourceBundleMessageSource.class); TestBean testBean = ctx.getBean(TestBean.class); Assert.assertTrue(testBean.getAppName().equals("spring mvc app")); String msg = msgs.getMessage("appname", new Object[]{new DefaultMessageSourceResolvable("appname")}, null); System.out.println(" "+ msg); String msg2 = msgs.getMessage("error.name", new Object[]{new DefaultMessageSourceResolvable("error.name")}, null); System.out.println(" "+ msg2); } }
精彩评论