國際化(應(yīng)用程序的功能),指在程序設(shè)計(jì)領(lǐng)域,將無需改寫源代碼即可使應(yīng)用程序能夠支持多種語言和數(shù)據(jù)格式的技術(shù);而本地化(動(dòng)詞)指使具備國際化功能的應(yīng)用程序支持某個(gè)特定的地區(qū)。
其中,Struts2國際化是建立在java國際化基礎(chǔ)之上的,即
需要為不同國家/語言提供對應(yīng)的國際化資源文件;Struts2框架根據(jù)請求中包含的Locale加載對應(yīng)的資源文件;通過程序代碼獲取資源文件中指定key對應(yīng)的消息值。國際化資源文件的配置主要包括全局范圍、包范圍和Action范圍共三種方式,具體實(shí)現(xiàn)如下:
全局范圍下:在src目錄下添加名為basename_language_country.PRoperties的資源文件,并在struts.xml文件中進(jìn)行常量配置<constant name="struts.custom.i18n.resources" value="baseName"/>;包范圍下:在包的根路徑下添加名為package_language_country.properties的資源文件,該包下的所有Action均可訪問該資源文件,注意文件名中的basename就是package;Action范圍下:在Action類文件所在路徑下添加名為ActionName_language_country.properties的資源文件;臨時(shí)指定資源文件:<s:i18n.../>標(biāo)簽的name屬性可指定臨時(shí)的國際化資源文件。 國際化資源文件的加載原則是與當(dāng)前Action類較近的被優(yōu)先加載。假設(shè)在某個(gè) CustomAction中調(diào)用了getText("username")訪問國際化資源文件的username屬性,則:
若Action類實(shí)現(xiàn)了TextProvider接口(常見于繼承ActionSupport類),則可以調(diào)用其getText()方法來訪問。
對于不帶占位符的屬性值:
采用s:text標(biāo)簽來訪問:<s:text name="key"/>;表單元素的label屬性:可替換為key屬性 或 使用getText()方法(需要對其進(jìn)行強(qiáng)制OGNL解析)。對于帶有占位符的屬性值:
采用s:text標(biāo)簽:在該標(biāo)簽中使用多個(gè)s:param標(biāo)簽來填充消息中的占位符;Struts2直接在國際化消息資源文件中通過 “${}” 使用表達(dá)式,該表達(dá)式將從值棧中獲取對應(yīng)的屬性值注意:可以利用標(biāo)簽和OGNL表達(dá)式來直接訪問值棧中的屬性值(對象棧和Map棧);例如,若當(dāng)前頁面來自于Action,則可以直接訪問Action中的屬性值。
核心測試代碼如下所示:
i18n_en_US.properties:
username=UserNamepassWord=Passwordsubmit=Submittime1=Time:{0}time2=Time:${date}i18n_zh_CN.properties:
username=/u7528/u6237/u540Dpassword=/u5BC6/u7801submit=/u63D0/u4EA4time1=/u65F6/u95F4/uFF1A{0}time2=/u65F6/u95F4/uFF1A${date}index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib uri="/struts-tags" prefix="s"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body> <a href="testI18n">Test...</a> <br> <!-- 需要值棧中有date屬性:可在Action類中定義 --> <s:text name="time1"> <s:param value="date"></s:param> </s:text> <br> <s:text name="time2"></s:text> <s:form> <!-- 注意:若theme="simple"則key屬性方式失效,需要使用s:text標(biāo)簽來訪問 --> <!-- key屬性方式: --> <s:textfield name="username" key="username"></s:textfield> <!-- getText()方式: --> <!-- 對象棧中有DefaultTextProvider實(shí)例,其提供有訪問國際化資源文件的getText()方法 --> <s:textfield name="password" label="%{getText('password')}"></s:textfield> <!-- key屬性方式: --> <s:submit key="submit"></s:submit> </s:form></body></html>TestI18nAction.java:
package com.qiaobc.struts.action;import java.util.Arrays;import java.util.Date;import com.opensymphony.xwork2.ActionSupport;public class TestI18nAction extends ActionSupport { private static final long serialVersionUID = 1L; private Date date = null; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public String execute() { date = new Date(); // 1. 在Action中訪問國際化資源文件的value值 String username = getText("username"); String password = getText("password"); String submit = getText("submit"); System.out.println(username + " , " + password + " , " + submit); // 2. 帶占位符的 String time1 = getText("time1", Arrays.asList(date)); System.out.println(time1); return "success"; }}struts.xml:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"><struts> <!-- 配置全局范圍內(nèi)的國際化資源文件 --> <constant name="struts.custom.i18n.resources" value="i18n"></constant> <package name="i18n" namespace="/" extends="struts-default"> <action name="testI18n" class="com.qiaobc.struts.action.TestI18nAction"> <result>/index.jsp</result> </action> </package></struts>該部分的關(guān)鍵在于Struts2框架如何確定Locale對象?即I18N攔截器。其實(shí)現(xiàn)效果如下圖所示:

只需要在超鏈接的后面添加request_locale的請求參數(shù),其值為語言國家代碼即可。
<!--注意:超鏈接必須是一個(gè)Struts2的請求,使得i18n攔截器工作--><a href="testI18n?request_locale=en_US">English </a><a href="testI18n?request_locale=zh_CN">中文 </a>新聞熱點(diǎn)
疑難解答