<bean:message key="welcome.title"/> 是 Struts 開發中極高頻的標籤,其背後涉及資源文件定位、加載、緩存及 Locale 解析等核心機制。本文通過源碼追蹤,完整還原從配置到消息獲取的全鏈路。
在 struts-config.xml 中典型配置:
<message-resources parameter="resources.application"/>
表面看似查找 application.properties,但 PropertyMessageResources 源碼揭示真實邏輯:
String name = config.replace('.', '/'); // resources/application
if (localeKey.length() > 0) {
name += "_" + localeKey; // resources/application_zh
}
name += ".properties"; // 擴展名寫死為 .properties
關鍵發現:
基礎名_Locale.properties 模式。ClassLoader.getResourceAsStream() 獲取輸入流,再由 Properties.load() 解析到 HashMap 緩存。Properties.load() 要求資源文件必須以 ISO-8859-1 編碼保存。若直接編寫中文會導致亂碼(顯示為 ???),解決方案:
native2ascii 工具轉換為 Unicode 轉義序列(如 \u4e2d\u6587)。getMessage() 實現了完整的回退機制:
while (true) {
loadLocale(localeKey); // 載入當前 Locale 資源
message = messages.get(messageKey(localeKey, key));
if (message != null) return message;
// 回退:去掉最後一個下劃線及後綴(如 _TW -> _zh -> "")
underscore = localeKey.lastIndexOf("_");
if (underscore < 0) break;
localeKey = localeKey.substring(0, underscore);
}
// 最後嘗試默認 Locale
if (!defaultLocale.equals(locale)) { ... }
查找順序:zh_TW → zh → default Locale → 基礎文件名.properties。
RequestUtils.getUserLocale() 揭示 Locale 獲取優先級:
Globals.LOCALE_KEY(鍵為 "org.apache.struts.action.LOCALE")。Accept-Language 推導(request.getLocale())。註:Locale 何時存入 Session 源碼中未直接體現,通常在登錄或 Locale 切換 Action 中手動設置。