JSF国际化(i18n)

 [JavaServerFaces是我学习的第一个web框架,虽然现在流行的是struts,但jsf还是被看好的,struts提供了很好的国际化支持,jsf同样提供了非常好的i18n支持,下面是自己学习过程中的一个整理,做项目的时候参考起来比较方便。由于是一个参考性的整理,读者需要有JSF和properties的知识]

当实现一个web应用程序时,比较好的方法是收集所有消息串,以资源文件的形式供程序使用。这个过程可便于保持消息一致性,更重要的是,它更便于在其他地方本地化应用程序。

jsf简化了这个过程。

1、建立properties资源包
首先,收集消息字符串并放到一个文件中,格式如下:
currentScore=your current socre is:
guessNext=Guess the next number in the sequence!
[有关该文件格式的详细说明,可以查看load方法的API文档中对java.util.Properties类的说明]
该文件必须使用.properties扩展名.
文件存放位置可以任意指定,推荐使用类似java包名的结构目录
本例位于:com.thizlinux.i18n
针对要支持的语言环境分别提供对应的资源文件(均存放于上面同一目录),
文件名格式如下:
source.properties [默认,必须,当无匹配资源包可用时使用]
source_en.properties
source_de.properties
source_zh.properties(重点:资源包文件不是用UTF-8编码,除127之外其他Unicode字符都被编码为uxxx转义序列。Java SDK实用程序native2ascii可以创建这些文件。因此该中文包文件需要使用nativ2ascii进行转义),在Eclipse下有一个很好的插件可以免去这项繁琐的操作,使得编辑资源文件极其简便。
该插件需要通过eclipse的SoftwareUpdate来安装,remote地址:http://propedit.sourceforge.jp/eclipse/updates/
如上所示,本地化资源包文件时,需要向文件名添加本地后缀:下划线后面
跟两个小写字母的ISO-639语言编码,可以从http://www.loc.gov/standards/ios639-2
找到所有两个和三个字母ISO-639语言编码的列表
上述三个文件分别为默认资源包、英语资源、德语资源包和中文资源包,对应的需要在应用程序配置文件中,如WEB-INF/faces-config.xml中设置默认和所支持的本地化
<faces-config>
    <application>
        <locale-config>
            <default-locale>en</default-locale>
            <supported-locale>de</supported-locale>
            <supported-locale>zh</supported-locale>
        </locale-config>
    </application>
</faces-config>
当浏览器连接到应用程序时,其HTTP头中通常会包含一个Accept-Language值(参见
http://www.w3.org/International/questions/qa-accept-lang-locale.html),
JSF读取该值并从所支持的本地化中找到最佳匹配,在浏览器中设置所匹配的语言环境。

2、jsf页面使用资源包
向jsf页面添加f:loadBundle元素
<f:loadBundle basename="com.thizlinux.i18n.source" var="src"/>
该元素会自动装载(该资源文件是由类加载器加载)对应locale下的资源包文件(根据_de、_zh的后缀进行判断),
加载的资源被影射到由var属性指定的src变量中保存在请求范围内
之后就可以使用值绑定表达式来访问消息字符串:
<h:outputText value="#{src.guessNext}"/>

3、应用程序本地化的设置,也就是Locale的设置
1)页面中:<f:view locale="de">
2)在应用程序配置文件中设置,如前所示的WEB-INF/faces-config.xml
3)程序代码中进行动态设置:
    UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
    viewRoot.setLocale(new Locale("de"));

4、程序代码中从资源包获取错误消息
在jsf的转换和验证阶段如果转换和验证失败,需要通过<h:messages/>和<h:message/>将错误消息回显给用户,为适应本地化的需要,代码中可以从资源包中获取本地化消息字符串并生成错误消息.
1)创建错误消息资源包
目录:com.thizlinux.i18n
资源文件:messages.properties
      messages_en.properties
      messages_zh.properties
文件内容示例:badCreditCardCharacter=Invalid card number.
          badCreditCardCharacter_detail=The card number contains invalid
                              characters.
      创建消息资源包需要注意的一点是,每个错误消息需要两个消息字符串:
      一个用于概要消息,一个用于细节消息。细节消息的资源ID通过在资源关键字
      后面添加“_detail”来标识。

2)使用
应用程序可以在配置文件中提供一个资源包名称,例如:
<faces-config>
    <application>
        
<message-bundle>com.thizlinux.i18n.messages</message-bundle>
    </application>
</faces-config>
代码中可以通过以下代码获得配置文件所指定的资源包名称
FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
String msgBundleName = app.getResourceBundle();
如果msgBundleName为空或没有在配置文件进行配置,在编写代码获取资源时需要硬编码指定(或通过其他方式获得)资源包名称,在有了资源包名称后通过以下代码获得资源字符串:
UIViewRoot viewRoot = context.getViewRoot();
Locale locale = viewRoot.getLocale();//此两行代码获取当前请求场所
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if (loader==null) loader = ClassLoader.getSystemClassLoader();//获得当前类加载器
                                ,如果为null则使
                                用系统类加载器
ResourceBundle bundle = ResourceBundle.getBundle(msgBundleName,locale,loader);
String msg = bundle.getString(dCreditCardCharacter_detail);
String msg_detail = bundle.getString(dCreditCardCharacter_detail);//获得概要消息和细节消息资源字符串
FacesMessage message = new FacesMessage(msg,msg_detail);//最后生成faces消息

3) 消息格式化器之占位符
在实际应用场景中,可能想让一些消息提供有关错误信息本质的详细信息。
例如,告诉用户其输入的信用卡号中的哪个字符是非法的,可以通过在资源文件的消息
字符串中包含占位符{0}、{1}等等,例如上例messages.properties中可以改为:
badCreditCardCharacter_detail=The card number contains the invalid charater {0}.
下面代码使用消息格式化器接收对象数组参数替换占位符,并返回格式化后的新字串
Object[] params = ...;//如params = new Object[]{ new Character(invalidCharacter) }
MessageFormat formatter = new MessageFormat(msg_detail,locale);
String msg_detail = formatter.format(params);
关于java.text.MessageFormat类的详细信息参考API

4)最佳实践
在使用资源包时候如果没有获取到需要的资源字符串,则应遵循JSF有关显示丢失资源的
协议,应返回如"???msg_detail???"格式的字符串,而不能任其为null或为空。
一个很好的且实用的范例程序参考:《Core JavaServer Faces》(中文版)chapter6转换和验证所提供的com.corejsf.util.Messages实用类(P197程序清单6-8).
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值