国际化(应用程序的功能),指在程序设计领域,将无需改写源代码即可使应用程序能够支持多种语言和数据格式的技术;而本地化(动词)指使具备国际化功能的应用程序支持某个特定的地区。
其中,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属性,则:
- 加载与CustomAction的类文件在同一路径下的资源文件CustomAction.properties;
- 加载与CustomAction实现的接口IChild在同一个路径下的资源文件IChild.properties;
- 加载与CustomAction父类Parent在同一个路径下的baseName为Parent.properties的资源文件;
- 若CustomAction实现ModelDriven接口,则对于getModel()方法返回的model对象,重新执行第1步操作;
- 查找当前包下package.properties资源文件;
- 沿着当前包上溯,直到最顶层包来查找package.properties资源文件;
- 查找struts.custom.i18n.resources常量指定baseName的资源文件;
- 直接输出该key对应的字符串值。
二、访问国际化资源文件内容
2.1 在Action类中访问
若Action类实现了TextProvider接口(常见于继承ActionSupport类),则可以调用其getText()方法来访问。
2.2 在JSP页面上访问
对于不带占位符的属性值:
- 采用s:text标签来访问:
<s:text name="key"/>; - 表单元素的label属性:可替换为key属性 或 使用getText()方法(需要对其进行强制OGNL解析)。
对于带有占位符的属性值:
- 采用s:text标签:在该标签中使用多个s:param标签来填充消息中的占位符;
- Struts2直接在国际化消息资源文件中通过 “${}” 使用表达式,该表达式将从值栈中获取对应的属性值
注意:可以利用标签和OGNL表达式来直接访问值栈中的属性值(对象栈和Map栈);例如,若当前页面来自于Action,则可以直接访问Action中的属性值。
核心测试代码如下所示:
i18n_en_US.properties:
username=UserName
password=Password
submit=Submit
time1=Time:{0}
time2=Time:${date}
i18n_zh_CN.properties:
username=\u7528\u6237\u540D
password=\u5BC6\u7801
submit=\u63D0\u4EA4
time1=\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拦截器。其实现效果如下图所示:
3.1 Locale对象确定流程
- Struts2使用i18n拦截器处理国际化,并且将其注册在默认的拦截器栈中;
- i18n拦截器在执行Action方法前,自动查找请求中名为request_locale 的参数。如果存在则将其转换为Locale对象,设为用户默认的Locale(代表国家/语言环境),并设置为session的 WW_TRANS_I18N_LOCALE属性;
- 如果request_locale参数不存在,则i18n拦截器从Session中获取WW_TRANS_I18N_LOCALE的属性值,若该值不为空,则将该属性值设置为用户默认的Locale;
- 若session中的WW_TRANS_I18N_LOCALE的属性值为空,则从ActionContext中获取Locale对象。
3.2 具体实现
只需要在超链接的后面添加request_locale的请求参数,其值为语言国家代码即可。
<!--注意:超链接必须是一个Struts2的请求,使得i18n拦截器工作-->
<a href="testI18n?request_locale=en_US">English </a>
<a href="testI18n?request_locale=zh_CN">中文 </a>
本文详细介绍了Struts2框架中的国际化(I18N)功能,包括如何配置和使用国际化资源文件,以及如何通过超链接动态加载不同的语言环境。
490

被折叠的 条评论
为什么被折叠?



