学习目标:
1、了解什么是国际化支持
2、掌握Java对国际化的支持
3、掌握Struts2对国际化的支持
学习过程:
如果你想你开发的应用程序可以在全世界使用,那么你首先要解决的问题就是语言的问题,jdk提供的国际化的功能意见很好的帮助我们解决了这个问题了。国际化英文单词是Internationalization,I为因为单词的第一个字母,18为这个单词的长度,而N代表这个单词的最后一个字母,所以又称I18N。
java使用国际化的方式是:把程序中的所有的标签、提示信息等都放在资源文件中,程序需要支持那些语言/国家(地区)环境,就必须提供对应的资源文件。资源文件是用属性文件,也就是使用key=value的格式,每个资源文件中的key不变,但value随不同的语言/国家(地区)而变化。
一、java对国际的支持
1、jdk支持的语言和国家(地区)信息。
我们可以通过Locale打印出所有的语言和国家(地区)信息的基本信息,包括名称和对应的代号,这个代号在后面我们写资源文件的时候需要用到,代码如下:
public static void main(String[] args) {
//jdk支持的国家(地区)语言
Locale []locales=Locale.getAvailableLocales();
for(Locale locale:locales){
System.out.print("语言代码:"+locale.getLanguage()+":名称"+locale.getDisplayLanguage()+"。");
System.out.println("国家(地区)的代码:"+locale.getCountry()+":名称"+locale.getDisplayCountry());
}
}
得到的信息如下:
语言代码:ja:名称日文。国家(地区)的代码:JP:名称日本
语言代码:es:名称西班牙文。国家(地区)的代码:PE:名称秘鲁
...
2、资源文件
资源文件的命名规范是:
配置文件的名称_语言代码_地区代码.properties
我们首先使用MyEclipse编写两个国际化文件(globleMessage_en_US.properties和globleMessage_zh_CN.properties),这里建议使用MyEclipse的properties插件进行编辑,这样这样就不需要专门对中文进行Unicode编码。如果你使用普通文本那么就需要使用jdk的native2ascii命令进行转码Unicode编码格式如下:
命令: native2ascii globleMessage_zh_CN.properties teme.properties
然后在将转好的编码拷贝替换到globleMessage_zh_CN.properties。
globleMessage_en_US.properties文件内容如下:
username=username
pass=password
address=address
headimage=headimage
language=USA
globleMessage_zh_CN.properties文件内容如下:
username=\u7528\u6237\u7684\u540D\u79F0
language=\u4E2D\u6587
pass=\u5BC6\u7801
address=\u5730\u5740
headimage=\u5934\u50CF
下面我们就可以使用java设定相应的本地化信息,就可以读取对应的配置文件的信息,通过key访问配置文件的内容。代码如下:
public static void main(String[] args) {
// 1、读取配置文件
ResourceBundle resourceBundle = ResourceBundle.getBundle(
"globleMessage", new Locale("en", "US"));
System.out.println(resourceBundle.getString("username"));
}
3、Java国际化包含占位符的消息
我们可以使用{下标的位置}来指定占位符。我在两个配置文件都添加以下信息:
英文:hello=Hello,{0}!
中文:hello=你好,{0}!
使用MessageFormat就可以格式化信息,代码如下:
public static void main(String[] args) {
// 1、读取配置文件
ResourceBundle resourceBundle = ResourceBundle.getBundle(
"globleMessage", new Locale("en", "US"));
System.out.println(resourceBundle.getString("username"));
//占位符
String result = MessageFormat.format(resourceBundle.getString("hello"), "刘德华");
System.out.println(result);
}
二、struts2对国际化的支持
Struts 2国际化是建立在Java国际化的基础之上,一样也是通过提供不同国家/语言环境的消息资源。我们还是使用上面的两个配置文件。
1、加载全局的资源文件。
在struts.properties文件中配置常量,只需要配置struts.custom.i18n.resources常量即可,代码如下:
struts.custom.i18n.resources=globleMessage
2、访问资源文件
Struts2访问国际化消息主要在如下3种方式:
(1)可以使用Struts2的
(2)在Action类中访问国际化消息,可以使用ActionSupport类的getText方法,该方法可以接受一个name 参数,该参数指定了国际化资源文件中的key。
(3)Label里输出国际化信息,可以为该表单标签指定一个key属性, 该key指定了国际化资源文件中的key.
在这里我们先使用第一种方式。其它方式我们以后再讲解。页面代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":"
+ request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>添加用戶</title>
</head>
<body>
<form action="adduser.action" method="post" enctype="multipart/form-data" >
<s:text name="username"></s:text>
<input name="user.username" />
<br />
<s:text name="pass"></s:text>:
<input name="user.passwd" />
<br />
<s:text name="address"></s:text>:
<input name="user.addr" />
<br />
<s:text name="headimage"></s:text>:
<input name="head" type="file"/>
<input type="submit" value="<s:text name="headimage"></s:text>" />
</form>
</body>
</html>
3、访问页面测试
现在打开浏览器,你的语言环境默认应该是中文的,所以显示的应该就是中文信息。如下图:
我们可以修改浏览器的语言环境,点击工具》》选项
然后添加新的语言,这里我们添加的是美国英语,然后把这个语言上移,点击确认后,重启浏览器,一定要重启后才会生效。
这时候我们再次访问,就是英文版的了。如下图
三、手动指定当前的语言环境,使用i18n拦截器
我们可以在页面上面添加两个超链接,让用户手动的选择当前的语言版本。在主页上面添加下面几行代码
<a href="#">English Ed</a> |
<a href="#">中文版</a>
当前的语言环境是:
<s:text name="language"></s:text>
要想实现手动的设置当前语言环境就需要使用i18n的拦截器,这个已经在默认拦截器栈中引用了,所以我们并不需要显示的引用,你可以打开文档看看它的解析,他会把用户当前的语言环境保持在session中,所以这个设置只对当次用户请求有效,这非常符合我们的要求,由于使用拦截器,而拦截器只能拦截action,所以我们这个设置必须要经过action才能生效,不能直接挑战去jsp页面。
需要修改session当期保存的语言环境,只需要提供请求格式如: foo.action?request_locale=en_US。这样美国英文环境就保存在session中了。
新建一个IndexAction类,并定义方法toIndex,这个方法什么都没有做。实现代码如下:
public class IndexAction extends ActionSupport{
public String toIndex(){
return SUCCESS;
}
}
在struts.xml中配置如下:
<action name="toIndex" class="com.action.IndexAction" method="toIndex">
<result>/index.jsp</result>
</action>
也是没有什么特殊的地方。修改index.jsp的超链接,在超链接的后面加上request_locale=语言环境
<a href="toIndex.action?request_locale=en_US">English Ed</a> |
<a href="toIndex.action?request_locale=zh_CN">中文版</a>
当前的语言环境是:
<s:text name="language"></s:text>
在进入这个action方法之前会经过就会进入i18n的拦截器,并修改session保存语言环境信息。当前的语言环境就会生效。
不过如果你现在直接访问userAdd.jsp,会发现语言环境还是没有生效,因为直接访问userAdd.jsp并不会经过i18n的拦截器,所以你不能这样做了。你可以修改UserAction类,添加一个方法,代码如下:
public String toAdduser(){
return SUCCESS;
}
struts.xml配置文件如下:
<action name="toAdduser" class="com.action.UserAction" method="toAdduser">
<result>/userAdd.jsp</result>
</action>
修改主页的超链接
<a href="toAdduser.action">添加用户</a>
这样就可以了。