国际化是很多Web系统中重要的功能部分,国际可以使用一套应用程序在不同的区域环境下显示不同的语言效果。因些为跨区域的应用开发提供了便利。因些在众多WEB开发框架中都提供了良好的国际化支持,下面我们来看一Strust2 框架中是如何实现国际化的。
1.SE环境上使用国际化
在开始了解Strsut2 国际化之前我们要先搞清楚国际化的原理。
首先我先在SE环境下使用一下java的国际化。
查看JavaAPI 我们会发现这样一个类: java.uil. ResourceBundle 这个类是资源包的意思,包含了特定语言环境的对象,如果程序需要某一特定语言环境下的资源时,应用程序会在该语言环境下加载它。
Java.util.Loacle 代表特定的地理,政治,文化区域的语言环境。
Locale(String language) 根据指定语言创建一个语言环境
Locale(String language, String country) 根据指定国家和语言创建一个语言环境。
下面是这个类的构造方法,在这个类中提供了很多常量表示一个区域。
Locale 类中还在一个方法 getAvailableLocales() 方法,获取所有已经安装的语言环境
getCountry() 获取区域环境名称
getDisplayCountry() 获取区域环境对应的代码
getLanuage() 获取区域环境下语言环称
getDiaplayLanuage() 获取区域环境下语言环境代码
下面我们可以打印一下:
Locale[] locales=Locale.getAvailableLocales(); for(Locale locale:locales){ //System.out.println(locale.getDisplayCountry()+"==="+locale.getCountry()); System.out.println(locale.getDisplayLanguage()+"===="+locale.getLanguage()); }下面我们看一下:
publicstaticvoid main(String[] args) { //获取系统当前默认Locale //Locale locale=Locale.getDefault(); Locale locale=Locale.US; //获取当前Locale对应的资源包 ResourceBundle bundle=ResourceBundle.getBundle("hellofile",locale); String value=bundle.getString("hello"); System.out.println(value); }
上面locale 代表的是美国语言环境,根据语言环境我可以得到一个资源包,ResourceBundle.getBundle("hellofile",locale); 第一个参数是资源文件的名字,第个就是区别语言环境,这样的话,我们就可以到美国语言环境下的一个资源包,下面对其进行操作取出该资源包下面的hello 字符串,打印来就是资源文件中的数据。资源文件如下:
hellofile_zh_CN.properties 文件:
hello = /u46f60/u597d!
Hellofile_en_US.properties 文件
hello = hello ni hao!
如何上面我们使用Loacle.US环境,打印出来就hello nihao! 如果采用Local.CN 打印出来就是“你好!“;
接着往下面看:
publicstaticvoid main(String[] args) { //Locale locale=Locale.getDefault(); Locale locale=Locale.US; ResourceBundle bundle=ResourceBundle.getBundle("hellofile",locale); String value=bundle.getString("hello"); String result=MessageFormat.format(value, new Object[]{"张呵"}); System.out.println(result); }
我们经常会看到一此资源配置文件中会出现占位符{0} 这样的东西:
当然我们也可以使用这样占位符,当程序运行时给其传参数。
hellofile_zh_CN.properties 文件:
hello = /u46f60/u597d {0} !
Hellofile_en_US.properties 文件
hello = hello ni hao {0}!
我们打算传一个姓名过来,只后显示,如何做呢?
查找javaAPI我们会发现一具java.util.MessageFormat 类,这个类提供了格式化对象,并将格式化之后的数据插入到模型中行当的位置。
因些通过MessageFormat.format(value, new Object[]{"张呵"}); 可以将对象数据中的东西,替换资源包中信息的占位符。从而达到传值的目的。
OK,上面是SE环境下如何使用国际化。
2.Strsut2的中的国际化
Strsut2 中主要包括两方面的国际化:
1. 静态信息的国际化 2。错误信息的国际化
1.在页面中使用Struts2 标签库 <s:text name=”login.username” /> 当JSP引擎解析到这样的标签时会在资源文件中找login.username 对应的值并显示出来。
在这里说一下,资源文件命名是要有规范的文件名_语言代码_国家区域代码.properties
并且这个(全局)资源文件要在strsut2.xml 中常量进行配置,才能起作用。
2.我们经常需要对表单验证的错误信息进行国际化
Validate() 方法的验证的错误信息;
首先我们查看一下ActionSupport 类的API,我们会发现里面有一堆getText() 方法的重载方法,这些方法是可以根据key获取资源文件中key对应的值。
getText(String key); 根据key获取值 getText(String key,String[] value); 可以给错误信息中的占位符进行传值
具体用法:
在向FieldErrors 或ActionErrors 中添加错误信息时使用:
This.addActionError(“username”,new String[]{username});
3. 校验框架中错误信息国际化使用
在配置中使用
<field name="username"> <field-validator type="requiredstring" short-circuit="false"> <param name="trim">true</param> <message key="username.xml.required" /> </field-validator> <field-validator type="stringlength"> <param name="minLength">6</param> <param name="maxLength">10</param> <message key="username.xml.inavlid" /> </field-validator> </field>
为错误的信息message 提供一个key 值,这样就可以实现错误信息国际化。
4.多个配置文件级别
上面我们使用是都是全局的资源配置文件,在strsuts.xml 和strust.properties 文件中指定的。但是在实际的开发中,往往需要更加细粒度的配置文件支持,因此Strsut2 还提供了包级别的资源文件和类级别的资源文件,范围小的资源配置文件会覆盖范围大的资源文件。
包级别资源文件:在一个包中,命名如下:package_zh_CN.properties
类级别的资源文件:在类的同包下,命名如下:类名(RegisterAction)_en_US.properties
5.使用i18n标签
<s:i18n name="temp"> <s:text name="hello"> <s:param>lilp</s:param> </s:text> </s:i18n>
在页面上使用这样的标签,指定在temp配置文件中找资源,上面的配置是在temp资源文件中找hello 对应的值,中间的占位符用lilp替换。
首先建一个strut2的项目这就不多说!
1.在struts.properties中加入如下代码
#国际化文件
struts.custom.i18n.resources=messageResources(这个是资源文件的前缀,如果要是有文件目录就这样写xxxx.xxx...messageResources)
或者在struts.xml里面加上
<constant name="struts.custom.i18n.resources" value="messageResources"></constant>
2.建一个languageAction
package com.hopsun.strust2.action; import java.util.Locale; import com.opensymphony.xwork2.ActionContext; public class InternationalAction { private String languageName; //这个是测试直接用request_locale=zh_CN/* public String ChangeLanguage() { return "success"; } //这个是测试 用我们自定义一个页面参数,更换语言类型 public String ChangeLanguage2() { Locale l = Locale.getDefault(); if(this.languageName==null){ l = new Locale("zh", "CN"); }else if (this.languageName.equals("ft")) { l = new Locale("zh", "TW"); } else if (this.languageName.equals("en")) { l = new Locale("en", "US"); } //获取Locale :ActionContext.getContext().getLocale(); // ActionContext.getContext().getSession().put("WW_TRANS_I18N_LOCALE", // l); ActionContext.getContext().setLocale(l); return "success"; } public String getLanguageName() { return languageName; } public void setLanguageName(String languageName) { this.languageName = languageName; } }3.把action交给spring来管理
<action name="Change" class="Inter" method="ChangeLanguage"> <result>/Internationalization.jsp</result> </action> <action name="Chan" class="Inter" method="ChangeLanguage2"> <result>/Internationalization.jsp</result> </action>5.资源文件
<%@ 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> <title>My JSP 'Internationalization.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <!-- 测试第一种 对应action 方法ChangeLanguage() request_locale--> <a href="<%=basePath%>Change.do?request_locale=zh_CN">中文简体</a> <a href="<%=basePath%>Change.do?request_locale=zh_TW">中文繁体</a> <a href="<%=basePath%>Change.do?request_locale=en_US">English</a><br> <!-- 测试测试自定义参数 对应action 方法ChangeLanguage2() languageName--> <a href="<%=basePath%>Change.do">中文简体</a> <a href="<%=basePath%>Change.do?languageName=ft">中文繁体</a> <a href="<%=basePath%>Change.do?languageName=en">English</a><br> <s:label key="language"/><input name="language"> <s:label key="name"/><input name="name"> <s:label key="age"/><input name="age"> <s:label key="sex"/><input name="sex"> </body> </html>