| 模式 | 觸發方式 | 適用場景 |
|---|---|---|
| 自動檢測 | 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 # 法文
login.username=用戶名,值中包含空格無需轉義。Locale 解析:language_country_variant。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);
}
}
<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"/>
<!-- 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"/> 內部流程:
ActionContext.getContext().getLocale()。ActionClass.properties → package.properties → global.properties。{0})→ 輸出。<%@ page contentType="text/html;charset=UTF-8" %>web.xml 過濾器鏈:CharacterEncodingFilter 設置 UTF-8(Spring Boot 自動配置)。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 #{...},架構更清晰。