I18N-国际化消息和日志

1/5/2008来源:Java教程人气:5988

摘要:

    对于许多软件开发者来说,一提到国际化(亦称为 i18n)支持就会感到害怕。 要使编写的代码能够面向外国使用者,确实需要费一翻思量,因为在现有软件的代码中添加国际化支持可不是一件轻而易举的事。
对于许多软件开发者来说,一提到国际化(亦称为 i18n)支持就会感到害怕。 要使编写的代码能够面向外国使用者,确实需要费一翻思量,因为在现有软件的代码中添加国际化支持可不是一件轻而易举的事。 假如您感觉到软件需要支持不同语言和语言环境,哪怕这种可能性很小,从一开始就做国际化项目的预备,比起项目开始后再试图添加国际化支持也要明智得多。

    有人问“国际化”是什么意思? 国际化远不止于将用户界面消息翻译成不同的语言。 它还涉及到处理不同的字符编码、日期/时间/货币的显示形式、以及跨多区域时存在的一些其他差异。

  介绍 i18nlog

    本文的目的并不在于讨论那些关于国际化的琐碎的方面,而是通过研究一个称为 "I18N Messages and Logging" (简称 i18nlog) 的开源项目,来介绍引入国际化功能时需要执行的一些必要的任务
i18nlog 答应您在 java 应用程序内集成国际化的消息,这是通过向以下内容提供 API 来完成的:
+标注 Java 类以识别国际化消息
+从所有支持的语言环境资源包中获取国际化消息
+创建特定于语言环境的异常,并在其中使用国际化的消息
+使用任何日志框架创建国际化消息日志
+自动生成特定于语言环境的资源包
+自动生成帮助及参考文档

  定义国际化消息

    国际化软件时一项最为乏味的工作莫过于维护资源绑定包了。 资源绑定包是包含 "name=value" 这种信息对的属性文件 (.PRoperties),其中 "name" 是资源绑定包的要害字字符串 (key string),而 "value" 是翻译过的消息字符串本身。 习惯上为每种语言创建一个资源绑定包,在每个绑定包中要害字的设置是唯一的,而各个要害字相关的值就要翻译成各种语言了。 资源绑定文件的名称应该指明它是为哪种语言创建的,例如,mybundle_en.properties 文件中的消息是用英语写的,而 mybundle_de.properties 包含德语消息。

    i18nlog 提供了一些用于定义资源绑定消息及其要害字字符串的标注--用于将资源注入到 i18nlog 的自定义 Ant 任务中,您可以自动生成资源绑定包,而不必为确保属性文件与访问属性文件的 Java 代码之间的一致性作过多的工作。

    @I18NMessage 标注被放在常量上,这些常量就是资源绑定包的要害字字符串使用的常量。 使用这些常量可以迫使执行编译时检查;例如代码中引入的拼写错误(如常量名称的拼写错误)和使用过时消息或已删除消息,这些错误在编译时就可以被探测到。 以下是使用此标注的示例:

java 代码
1.        @I18NMessage( "Hello, {0}. You last visited on {1,date}" )   
2.        public static final String MSG_WELCOME = "example.welcome-msg";  


    上面的示例定义了一条国际化消息。 常量的值定义了资源绑定包的要害字字符串(key string)。 标注的值是一条实际翻译好的消息。 您可以将这些标注过的常量放到应用程序的任何类或接口中。 可以将它们放在单独的类或接口中(将所有消息定义集中到一个地点),也可以放在使用到它们的类中。

    @I18NResourceBundle 标注用于定义存放消息的资源绑定包文件(.properties 文件)。 它可以标注整个类或接口,也可以标注特定的部分。 假如您标注了一个类或接口,则该类或接口中的所有 @I18NMessage 标注都将被存储在该标注定义的资源绑定包中(默认情况下)。 假如只将标注放在特定的常量上,那么它就只是那个常量的绑定包。 以下是使用此标注的示例:

java 代码
1.        @I18NResourceBundle( baseName = "messages",   
2.                             defaultLocale = "en" )  


    以上代码的意思是,所有被 @I18NMessage 标注的相关消息都将放置在名为 messages_en.properties 绑定包文件中。 下面是一个更复杂的示例(包含一系列国际化消息的接口):

java 代码
1.        @I18NResourceBundle( baseName = "messages",    
2.                             defaultLocale = "en" )    
3.        public interface Messages {    
4.           @I18NMessage( "Hello, {0}. You last visited on {1,date}" )    
5.           String MSG_WELCOME = "welcome-msg";    
6.          
7.           @I18NMessage( "An error occurred, please try again" )    
8.           String MSG_ERR = "error-occurred";    
9.          
10.           @I18NMessage( "The value is {0}" )    
11.           String MSG_VALUE = "value";    
12.        }  


  检索国际化消息

    定义了国际化常量后,就可以使用 i18nlog 的核心类提供的 API:mazz.i18n.Msg。 该 API 用于装载存放于资源绑定属性文件中的消息。 它还用于将值作为变量参数进行传递,从而替换消息中的占位符(例如, {0}, {1,date})。 另外,此 API 将您从直接使用 JDK 类进行编码的工作中解放出来,也许您需要阅读一下 Javadoc 的 java.text.MessageFormat 部分,以获得对 i18nlog 工作原理的初步熟悉,尤其是它如何使用本地化的数据替换占位符。

下面是 Msg 类的使用实例:

java 代码
1.        // 使用静态工厂方法创建一个 Msg 对象   
2.        // 假设默认绑定包的名字是 "messages"  
3.        System.out.println( Msg.createMsg( Messages.MSG_WELCOME,  
4.                                           name,  
5.                                           date ) );  



java 代码
1.        // 使用构造函数创建一个 Msg 对象   
2.        Msg msg = new Msg( new Msg.BundleBaseName("messages") );  
3.        try {  
4.           String hello = msg.getMsg(Messages.MSG_WELCOME, name, date );  
5.           ... do something ...  
6.        }  
7.        catch (Exception e) {  
8.           throw new RuntimeException( msg.getMsg( Messages.MSG_ERR ) );  
9.        }