struts国际化信息的存储格式
struts默认使用PropertyMessageResources实现国际化的相关处理,该类有两个属性
protected HashMap messages = new HashMap(); //该Map存放国际化信息
protected HashMap locales = new HashMap(); // 辅助map,用于判定某国际化文件是否被初始化
key和value
PropertyMessageResources中有一个方法loadLocale(String localeKey),该方法主要目的是读取国际化信息文件并将信息进行处理
1. localeKey的值是Locale.toString()的值,如果浏览器配置为中国大陆,该值将会是zh_CN;如果使用美式英文,该值是en_US
2. 根据localeKey的值在locales(辅助Map)中查询value,第一次进入时该值不存在,方法会进行 下一步逻辑,否则终止;简单的说,locales会存放一个以国际化信息(Locale.toString()的值)为key和value的键值对,用于标识该国际化信息是否已经被初始化。
3. 假设是第一次,该方法获取struts-config.xml中配置的国际化文件配置项的parameter(假设我们配置的是resources.ApplicationResources),struts会根据该值生成一个国际化信息文件的路径:resources/ApplicationResources.properties或resources/ApplicationResources_en_US.properties或resources/ApplicationResources_zh_CN.properties眼熟吧?这个也就是我们在src文件家中国际化文件的路径。三个都生成?no,localeKey决定了读那个文件
4. 读完文件该放入messages(国际化信息Map)了,怎么放?看这段代码
protected String messageKey(String localeKey, String key) {
return (localeKey + "." + key);
}
假设国际化信息中有一个值userName=用户姓名,在中文大陆环境下,messages(国际化信息Map)存放的信息是key=zh_CN.userName,value=用户姓名;在美式英文环境下的信息是key=en_US.userName,value=用户姓名
5. PropertyMessageResources对外提供一个getMessage(Locale locale, String key)方法用于获取国际化信息,根据上面的内容就明白了,locale和key是用来生成messages(国际化信息Map)的key值,value很容易从messages(国际化信息Map)获取。
附一段代码
protected synchronized void loadLocale(String localeKey) {
if (log.isTraceEnabled()) {
log.trace("loadLocale(" + localeKey + ")");
}
// Have we already attempted to load messages for this locale?
if (locales.get(localeKey) != null) {
return;
}
locales.put(localeKey, localeKey);
// Set up to load the property resource for this locale key, if we can
String name = config.replace('.', '/');
if (localeKey.length() > 0) {
name += "_" + localeKey;
}
name += ".properties";
InputStream is = null;
Properties props = new Properties();
// Load the specified property resource
if (log.isTraceEnabled()) {
log.trace(" Loading resource '" + name + "'");
}
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = this.getClass().getClassLoader();
}
is = classLoader.getResourceAsStream(name);
if (is != null) {
try {
props.load(is);
} catch (IOException e) {
log.error("loadLocale()", e);
} finally {
try {
is.close();
} catch (IOException e) {
log.error("loadLocale()", e);
}
}
}
if (log.isTraceEnabled()) {
log.trace(" Loading resource completed");
}
// Copy the corresponding values into our cache
if (props.size() < 1) {
return;
}
synchronized (messages) {
Iterator names = props.keySet().iterator();
while (names.hasNext()) {
String key = (String) names.next();
if (log.isTraceEnabled()) {
log.trace(" Saving message key '" + messageKey(localeKey, key));
}
messages.put(messageKey(localeKey, key), props.getProperty(key));
}
}
}