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)); } } }