首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Struts 2 國際化實戰:自動檢測、用戶切換與資源文件最佳實踐

     編輯:Java 相關知識

三種國際化模式

模式觸發方式適用場景
自動檢測HTTP Accept-Language 頭無需用戶干預、面向大眾的公開站點
用戶手動選擇頁面下拉/鏈接攜帶 locale=zh_CN後台管理、個性化需求強的系統
混合模式(推薦)自動檢測為默認,提供切換入口,選擇持久化到 Session絕多數商業應用

資源文件命名規範

src/main/resources/
├── global.properties              # 默認 (en_US)
├── global_zh_CN.properties        # 簡體中文
├── global_zh_TW.properties        # 繁體中文
├── global_en_US.properties        # 英文
├── global_ja_JP.properties        # 日文
└── global_fr_FR.properties        # 法文
  • 文件編碼必須為 UTF-8(IDEA/File Encodings 設置)。
  • 鍵值格式:login.username=用戶名,值中包含空格無需轉義。
  • Struts 2 自動按 Locale 解析:language_country_variant。

實現混合模式:攔截器 + Session 持久化

1. 自定義 Locale 攔截器

public class LocaleInterceptor extends AbstractInterceptor {
    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        
        // 1. 參數優先:用戶主動切換
        String paramLocale = request.getParameter("locale");
        if (StringUtils.isNotBlank(paramLocale)) {
            Locale locale = Locale.forLanguageTag(paramLocale.replace('_', '-'));
            if (isValidLocale(locale)) {
                session.setAttribute(ActionContext.LOCALE, locale);
            }
        }
        
        // 2. Session 次之:用戶歷史選擇
        Locale sessionLocale = (Locale) session.getAttribute(ActionContext.LOCALE);
        if (sessionLocale != null) {
            ActionContext.getContext().setLocale(sessionLocale);
        } else {
            // 3. 最後回退:瀏覽器 Accept-Language
            ActionContext.getContext().setLocale(request.getLocale());
        }
        return invocation.invoke();
    }
    
    private boolean isValidLocale(Locale locale) {
        return Arrays.asList(Locale.getAvailableLocales()).contains(locale);
    }
}

2. struts.xml 註冊攔截器棧

<interceptors>
  <interceptor name="locale" class="com.example.interceptor.LocaleInterceptor"/>
  <interceptor-stack name="i18nStack">
    <interceptor-ref name="locale"/>
    <interceptor-ref name="defaultStack"/>
  </interceptor-stack>
</interceptors>

<default-interceptor-ref name="i18nStack"/>

3. 頁面切換入口

<!-- JSP -->
<select id="localeSelect" onchange="location.href=this.value">
  <option value="?locale=zh_CN"><s:text name="lang.zh_CN"/></option>
  <option value="?locale=en_US"><s:text name="lang.en_US"/></option>
  <option value="?locale=ja_JP"><s:text name="lang.ja_JP"/></option>
</select>

<!-- 或純鏈接 -->
<a href="?locale=zh_TW"><s:text name="lang.zh_TW"/></a>

標籤庫自動解析機制

<s:text name="login.username"/> 內部流程:

  1. 獲取 ActionContext.getContext().getLocale()。
  2. 按優先級查找資源包:ActionClass.properties → package.properties → global.properties。
  3. 按 Locale 精確匹配 → 語言匹配 → 默認文件。
  4. 找到鍵值 → 格式化參數(如 {0})→ 輸出。

關鍵配置檢查清單

  • ✅ 所有 JSP 頁面頭部:<%@ page contentType="text/html;charset=UTF-8" %>
  • ✅ web.xml 過濾器鏈:CharacterEncodingFilter 設置 UTF-8(Spring Boot 自動配置)。
  • ✅ 資源文件編碼 UTF-8,不要用 native2ascii 轉義(現代 IDE 直接編輯 UTF-8)。
  • ✅ 所有提示信息、錯誤碼、郵件模板、PDF 模板全部外部化到資源文件。
  • ✅ 數據庫存儲用戶偏好 Locale(user_prefs.locale),登入時自動載入 Session。

進階:複數形式與日期/貨幣格式化

<!-- 資源文件 -->
items.found={0,number} 個項目
items.found={0,number,integer} items found

<!-- JSP 使用 MessageFormat -->
<s:text name="items.found">
  <s:param><s:property value="total"/></s:param>
</s:text>

<!-- 日期貨幣格式化 -->
<s:date name="order.date" format="yyyy-MM-dd HH:mm" />
<s:date name="order.date" format="short" /> <!-- 使用 Locale 默認短格式 -->
<s:number name="order.amount" format="currency" />

總結

Struts 2 國際化核心在於 LocaleInterceptor 統一解析策略(參數 → Session → 瀏覽器),配合UTF-8 資源文件 + 標籤庫自動解析,實現零侵入式多語言支援。新專案建議直接使用 Spring MessageSource + Thymeleaf #{...},架構更清晰。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved