2.6 程序国际化
一个程序或Web应用如果需要面对多国家或区域的用户,那么不可避免地要实现国际化。国际化也是一个企业级应用必不可少的功能。Struts 2提供了非常好的国际化支持,只需几个简单的配置文件就能完成应用国际化。
2.6.1 输出中文的校验错误信息
前面只是简单地进行了输入校验,更多的输入校验方面的知识将在后面章节进行详细讲解。下面来完善该登录案例,使得该应用能够提示中文的校验错误信息。
因为addFieldError方法中的第二个参数用来指定错误信息,所以只需将那些错误信息修改成使用中文,就可以使得该登录案例提示中文的校验错误信息,代码如下所示。
//如果用户名为null,或者为空的话,那么提示错误信息 if(getUname() == null —— "".equals(getUname().trim())){ this.addFieldError("uname", "必须输入用户名"); } //如果密码为null,或者为空的话,那么提示错误信息 if(getUpassword() == null —— "".equals(getUpassword().trim())){ this.addFieldError("upassword", "必须输入密码"); }
这时在登录页面中不输入任何的用户信息,直接单击“登录”按钮,页面将显示中文的校验错误信息,如图2.14所示。
通过仔细思考,发现通过这种方式确实可以实现提示中文的错误提示信息,但是采用这种硬编码的方式有许多的缺点。
(1)缺乏灵活性。如果需要修改错误提示信息,则必须修改Action代码。
(2)代码严重冗余。如果需要提供多国的语言提示信息,则必须将应用复制成多份。
为了解决这些缺点,Struts 2提供了非常好的解决方案,那就是国际化。通过Struts 2的国际化支持,可以非常容易地显示不同国家或语言的错误提示信息。
2.6.2 国际化资源文件
国际化牵涉的知识非常多,这里也只是作简单的介绍,在后面的讲解中将对其进行详细的讲解。首先来先看程序国际化的示意图,如图2.15所示。
图2.14 提示中文错误信息
图2.15 程序国际化示意图
在登录页面中,不是直接输出信息,而是输出一个key值,该key值在不同语言环境下找到对应资源文件下的对应信息。如果是中文用户浏览该登录页面,那么将从中文资源文件中取出对应key值的字符串信息,因此返回给用户的是一个中文页面。如果是美国用户,那么将从英文资源中取得对应key值的字符串信息,因此返回给用户的是一个英文页面。如果程序要支持更多的语言,是不是只用增加相应资源文件即可?
下面介绍如何创建资源文件。资源文件的后缀名为“properties”。资源文件中包含的就是一些键值对(key-value),如“key1=登录”。在登录页面中就是通过key值来找到对应资源文件中的字符串信息的。下面是中文环境下的资源文件的代码。
login.title = 登录 login.username = 用户名 login.password = 密码
如果资源文件中包含非西欧字符,则必须将该字符转换成Unicode编码字符。因此可以使用native2ascii命令来处理转换该字符。找到JDK安装目录中bin目录下的“native2ascii.exe”文件,双击运行该程序。在该程序中输入中文,如“登录”,按回车键后程序会输出转换后的Unicode编码字符,如图2.16所示。
图2.16 使用native2ascii转换字符
可以将这些Unicode编码字符复制到相应的资源文件中,代码如下所示。
login.title = \u767B\u5F55 login.username = \u7528\u6237\u540D login.password = \u5BC6\u7801
也可以指定源文件和目标文件,这样就会将源文件中的字符转换成Unicode编码字符,然后放到目标文件中,命令格式如下。
native2ascii 源文件文件 目标文件
资源文件的命名规则也是非常严格的,如果不按照这样的命名,那么程序就无法完成国际化了。资源文件的命名规则如下。
basename_语言代码_国家代码.properties
所以上面的中文环境资源文件可以命名为“messageResource_zh_CN.properties”。根据同样的方法添加英文环境资源文件“messageResource_zh_CN.properties”,代码如下所示。
login.title = login login.username = username login.password = password
编写完资源文件后,将这些资源文件保存在项目的WEB-INF/classes目录下。
2.6.3 加载资源文件
资源文件已经创建好了,但是程序并不知道这些资源文件,因此必须配置这些资源文件并加载它们。Struts 2提供了非常多的加载国际化资源文件方式。其中最常用的就是加载全局的资源文件。可以通过两种方法来加载全局的资源文件。
第一种方法就是在“struts.xml”文件中配置一个struts.custom.i18n.resources常量。在struts.xml增加常量是通过在<struts>根元素下新建一个<constant>元素来完成的,其中name属性用来设定常量名,value属性用来指定属性值。添加代码如下所示。
<! -- 指定资源文件baseName为messageResource --> <constant name="struts.custom.i18n.resources" value="messageResource"> </constant>
第二种方法就是在“struts.properties”文件中配置一个“struts.custom.i18n.resources”常量。新建一个“struts.properties”文件,该文件也是一个资源文件,所以也是使用键值对的形式来配置。在该文件中的配置资源文件的basename为messageResource。添加代码如下所示。
struts.custom.i18n.resources=messageResource
同样将“struts.properties”文件保存在WEB-INF/classes目录下。
2.6.4 输出国际化信息
如果需要在JSP页面输出国际化信息,则可以通过Sturts 2提供的<s:text>标签来输出国际化信息。<s:text>标签的格式如下。
<s:text name="messageKey">
其中messageKey对应国际化资源文件中的key。
如果是在表单标签中,如单行文本框、密码框等中要输出国际化信息,可以通过指定key属性来指定key值。修改“login.jsp”登录页面代码如下所示。
<%@page contentType="text/html; charset=gb2312"%> <%@taglib prefix="s" uri="/struts-tags"%> <html> <head> <title><s:text name="login.title"></s:text></title> </head> <body> <center> <s:text name="login.title"></s:text> <%--登录表单--%> <s:form action="login"> <s:textfield name="uname" key="login.username"></s:textfield> <s:password name="upassword" key="login.password"></s:password> <s:submit value="登录"></s:submit> <s:reset value="重置"></s:reset> </s:form> </center> </body>
打开浏览器,访问登录页,页面显示效果如图2.17所示。
因为使用的是中文的操作系统,所以IE默认的语言环境为中文。可以通过IE属性配置来更改IE的默认语言环境。选择菜单栏中的“工具”→“Internet选项”命令,打开“Internet选项”对话框,如图2.18所示。单击“语言”按钮打开“语言首选项”对话框,如图2.19所示。
图2.17 用户登录页
图2.18 “Internet选项”对话框
在“语言首选项”对话框中可以通过“添加”按钮来添加语言环境。也可以通过上移和下移来设定首选的语言环境。这里设置“英语(美国)”为首选的语言环境。然后单击“确定”按钮,设置本地的语言环境为美国英语。刷新用户登录页“login.jsp”,页面显示效果如图2.20所示。
图2.19 “语言首选项”对话框
图2.20 用户登录页
2.6.5 输出国际化的校验错误信息
通过前面的配置,登录页面已经实现了国际化。其实校验错误信息也是可以实现国际化的。其用法完全一样,可以通过ActionSupport类提供的getText方法指定key,来获得国际化的错误提示。下面演示如何实现校验错误信息的国际化。
步骤如下。
(1)在中文资源文件“messageResource_zh_CN.properties”中添加校验错误信息键值对,代码如下所示。
password.required = 密码必须输入 username.required = 用户名必须输入!
使用native2ascii命令将代码转换成Unicode编码字符如下。
password.required = \u5BC6\u7801\u5FC5\u987B\u8F93\u5165 username.required = \u7528\u6237\u540D\u5FC5\u987B\u8F93\u5165
(2)在英文资源文件“messageResource_en_US.properties”中添加校验错误信息键值对,代码如下所示。
password.required = password is requested username.required = username is requested
(3)在LoginAction类的validate方法中通过getText方法获得国际化的错误提示,修改代码如下所示。
public void validate() { if(getUname() == null —— "".equals(getUname().trim())){ this.addFieldError("uname", getText("username.required")); } if(getUpassword() == null —— "".equals(getUpassword().trim())){ this.addFieldError("upassword", getText("password.required")); } }
打开浏览器,访问登录页地址。不输入任何用户信息,直接单击“登录”按钮,页面显示效果如图2.21所示。
图2.21 提示中文错误信息
设置本地的语言环境为美国英语。不输入任何用户信息,直接单击“登录”按钮,页面显示效果如图2.22所示。
图2.22 提示英文错误信息