我用属性文件(例如:messages_en_US.properties、messages_de_DE.properties)制作了一个支持 i18n 的 Spring(2.5.6) webapplication。
这个 .properties 文件带有 uni-codes。例如:
busy = Besch\u00E4ftigt
当从 messageSource
中读取 busy
关键字时,会给出以下结果:
...
private static ReloadableResourceBundleMessageSource messageSource;
/**
* Gets a message from the resources (.properties) defined in the applicationContext.xml
*
* @param input string to hook up
* @return the the message hooked up from the resources
*/
public static String getMessage(String input){
System.out.println(input); //busy
System.out.println(messageSource.getDefaultEncoding()); //UTF-8
System.out.println(messageSource.getMessage(input, null, null)); //Beschu00E4ftigt
return messageSource.getMessage(input, null, null);
}
...
所以没有 \
服务器上的文件也是UTF-8:
出现问题的环境:
- Tomcat 5.5.28(从
common/lib
运行jsp-api.jar
和servlet-api.jar
) - JDK 1.5.0_22
JSTL 1.1.2(从应用
lib
读取)Tomcat 6.0.32(从
lib
运行jsp-api.jar
和servlet-api.jar
)- JDK 1.5.0_22
- JSTL 1.1.2(从应用程序
lib
读取)
解决问题的环境(一模一样的分布):
- Tomcat 6.0.32(从 lib
运行 jsp-api.jar
和 servlet-api.jar
)
- JDK 1.6.0_13
- JSTL 1.1.2(从应用程序lib
中读取)
如果您需要更多信息,请告诉我。不要说我需要更新我的 JDK,因为这是不可能的。
更新applicationContext.xml中的绑定(bind)messageSource
<b:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<b:property name="defaultEncoding" value="UTF-8"/>
<b:property name="fallbackToSystemLocale" value="false" />
<b:property name="basenames">
<b:list>
<b:value>classpath:messages</b:value>
<b:value>/public/custom/i18n/portalmessages</b:value>
</b:list>
</b:property>
<b:property name="cacheSeconds" value="1"/>
</b:bean>
更新 2:将资源属性文件放在类路径中并使用类加载器:
URLClassLoader cl = (URLClassLoader) IOUtils.class.getClassLoader();
InputStream resourceAsStream = cl.getResourceAsStream("messages_de_DE.properties");
Properties prop = new Properties();
prop.load(resourceAsStream);
System.out.println("From classpath --> " + prop.get("busy")); //Beschäftigt
System.out.println("From i18n folder --> " + I18nFunctions.getMessage("busy")); //Beschu00E4ftigt
最佳答案
我查看了 DefaultPropertiesPersister
的源代码(它被 ReloadableResourceBundleMessageSource
内部使用)。
如果指定了 defaultEncoding
,属性将从 Reader
中逐行手动加载,而不是使用传统的 Properties.load()
方法。
在将键/值对添加到 Properties
对象之前,unescape()
方法在 String
上调用
protected String unescape(String str) {
StringBuffer outBuffer = new StringBuffer(str.length());
for (int index = 0; index < str.length();) {
char c = str.charAt(index++);
if (c == '\\') {
c = str.charAt(index++);
if (c == 't') {
c = '\t';
}
else if (c == 'r') {
c = '\r';
}
else if (c == 'n') {
c = '\n';
}
else if (c == 'f') {
c = '\f';
}
}
outBuffer.append(c);
}
return outBuffer.toString();
}
这是 \
字符被删除的地方。
如果你创建一个 DefaultPropertiesPersister
的子类,如下所示
package com.something;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.util.DefaultPropertiesPersister;
public class MyPropertiesPersister extends DefaultPropertiesPersister {
protected String unescape(String str)
{
return StringEscapeUtils.unescapeJava(str);
}
}
像这样在你的spring配置中设置它:
<b:bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<b:property name="defaultEncoding" value="UTF-8"/>
<b:property name="fallbackToSystemLocale" value="false" />
<b:property name="basenames">
<b:list>
<b:value>classpath:messages</b:value>
<b:value>/public/custom/i18n/portalmessages</b:value>
</b:list>
</b:property>
<b:property name="cacheSeconds" value="1"/>
<b:property name="propertiesPersister">
<b:bean class="com.something.MyPropertiesPersister"/>
</b:property>
</b:bean>
它会工作.. 可能需要进一步的 jiggery-pokery 才能准确获得您想要的与其他编码等相关的内容:)
关于java - 从 messageSource 读取 unicode 给 Java 5 带来了问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5340183/