国际化(应用程序的功能),指在程序设计领域,将无需改写源代码即可使应用程序能够支持多种语言和数据格式的技术;而本地化(动词)指使具备国际化功能的应用程序支持某个特定的地区。
其中,Struts2国际化是建立在java国际化基础之上的,即
需要为不同国家/语言提供对应的国际化资源文件;Struts2框架根据请求中包含的Locale加载对应的资源文件;通过程序代码获取资源文件中指定key对应的消息值。国际化资源文件的配置主要包括全局范围、包范围和Action范围共三种方式,具体实现如下:
全局范围下:在src目录下添加名为basename_language_country.PRoperties的资源文件,并在struts.xml文件中进行常量配置<constant name="struts.custom.i18n.resources" value="baseName"/>
;包范围下:在包的根路径下添加名为package_language_country.properties的资源文件,该包下的所有Action均可访问该资源文件,注意文件名中的basename就是package;Action范围下:在Action类文件所在路径下添加名为ActionName_language_country.properties的资源文件;临时指定资源文件:<s:i18n.../>
标签的name属性可指定临时的国际化资源文件。 国际化资源文件的加载原则是与当前Action类较近的被优先加载。假设在某个 CustomAction中调用了getText("username")
访问国际化资源文件的username属性,则:
若Action类实现了TextProvider接口(常见于继承ActionSupport类),则可以调用其getText()方法来访问。
对于不带占位符的属性值:
采用s:text标签来访问:<s:text name="key"/>
;表单元素的label属性:可替换为key属性 或 使用getText()方法(需要对其进行强制OGNL解析)。对于带有占位符的属性值:
采用s:text标签:在该标签中使用多个s:param标签来填充消息中的占位符;Struts2直接在国际化消息资源文件中通过 “${}” 使用表达式,该表达式将从值栈中获取对应的属性值注意:可以利用标签和OGNL表达式来直接访问值栈中的属性值(对象栈和Map栈);例如,若当前页面来自于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标签来访问 --> <!-- key属性方式: --> <s:textfield name="username" key="username"></s:textfield> <!-- getText()方式: --> <!-- 对象栈中有DefaultTextProvider实例,其提供有访问国际化资源文件的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> <!-- 配置全局范围内的国际化资源文件 --> <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>该部分的关键在于Struts2框架如何确定Locale对象?即I18N拦截器。其实现效果如下图所示:
只需要在超链接的后面添加request_locale的请求参数,其值为语言国家代码即可。
<!--注意:超链接必须是一个Struts2的请求,使得i18n拦截器工作--><a href="testI18n?request_locale=en_US">English </a><a href="testI18n?request_locale=zh_CN">中文 </a>新闻热点
疑难解答