天天看点

国际化 Java 应用程序

编写:徐建祥([email protected])

时间:2006-08-18 03:42

来自:http://www.anymobile.org

<术语>

国际化:internationalize,简称i18n,是指应用程序可以适应不同语言和地区的变化而变化的方案。

本地化:localization,检查l10n,是指应用程序适应某特定语言和地区的过程。

软件国际化是软件发展之必然,几乎所有的大众软件都支持多语言,最常见的就是英文软件的汉化版。

Java语言提供了基于unicode的国际化支持。通过Locale对象定义地区、语言、操作系统等信息,调用ResourceBundle的getBundle方法实现资源文件的数据绑定,轻松本地化不同的语言版本。

通过 ResourceBundle 和 Locale 2个类的定义可以看出 java 读取资源的流程为:language, country, variant -n-> language, country -n-> language -n-> Locale.getDefault()。

国际化 Java 应用程序

ResourceBundle.getBundle(String baseName)

国际化 Java 应用程序

ResourceBundle.getBundle(String baseName, Locale locale)

国际化 Java 应用程序
国际化 Java 应用程序

Locale(String language)

国际化 Java 应用程序

Locale(String language, String country)

国际化 Java 应用程序

Locale(String language, String country, String variant)

ResourceBundle 储存了键-值对形式的本地特殊化对象,如String,分为2种:ListResourceBundle和PropertyResourceBundle。

前者通过.class程序实现,后者通过.properties配置文件实现本地化,样例如下:

1、ListResourceBundle Example

1.1 默认(测试环境为中文)资源类

国际化 Java 应用程序
国际化 Java 应用程序

package  org.anymobile.test;

国际化 Java 应用程序
国际化 Java 应用程序

import  java.util.ListResourceBundle;

国际化 Java 应用程序
国际化 Java 应用程序
国际化 Java 应用程序

public   class  Rb  extends  ListResourceBundle

国际化 Java 应用程序

{

国际化 Java 应用程序

    static final Object[][] contents = {

国际化 Java 应用程序

            { "CHG", "修改" }, 

国际化 Java 应用程序

            { "MSG", "消息" }, 

国际化 Java 应用程序

            { "BYE", "再见" }

国际化 Java 应用程序

    };

国际化 Java 应用程序
国际化 Java 应用程序

    public Object[][] getContents()

国际化 Java 应用程序

    {

国际化 Java 应用程序

        return contents;

国际化 Java 应用程序

    }

国际化 Java 应用程序

}

1.2 英文资源类

国际化 Java 应用程序
国际化 Java 应用程序

package  org.anymobile.test;

国际化 Java 应用程序
国际化 Java 应用程序

import  java.util.ListResourceBundle;

国际化 Java 应用程序
国际化 Java 应用程序
国际化 Java 应用程序

public   class  Rb_en  extends  ListResourceBundle

国际化 Java 应用程序

{

国际化 Java 应用程序

    static final Object[][] contents = {

国际化 Java 应用程序

            { "CHG", "change" },

国际化 Java 应用程序

            { "MSG", "message" },

国际化 Java 应用程序

            { "BYE", "bye" }

国际化 Java 应用程序

    };

国际化 Java 应用程序
国际化 Java 应用程序

    public Object[][] getContents()

国际化 Java 应用程序

    {

国际化 Java 应用程序

        return contents;

国际化 Java 应用程序

    }

国际化 Java 应用程序

}

1.3 测试类

国际化 Java 应用程序
国际化 Java 应用程序

package  org.anymobile.test;

国际化 Java 应用程序
国际化 Java 应用程序

import  java.util.Locale;

国际化 Java 应用程序

import  java.util.MissingResourceException;

国际化 Java 应用程序

import  java.util.ResourceBundle;

国际化 Java 应用程序
国际化 Java 应用程序
国际化 Java 应用程序

public   class  MyListResourceBundle

国际化 Java 应用程序

{

国际化 Java 应用程序

    public static void main( String[] args )

国际化 Java 应用程序

    {

国际化 Java 应用程序

        String baseName = "org.anymobile.test.Rb";

国际化 Java 应用程序

        String key = "BYE";

国际化 Java 应用程序

        try

国际化 Java 应用程序

        {

国际化 Java 应用程序

            ResourceBundle res = ResourceBundle.getBundle( baseName );

国际化 Java 应用程序

            System.out.println( res.getString( key ) );

国际化 Java 应用程序
国际化 Java 应用程序

            res = ResourceBundle.getBundle( baseName, Locale.ENGLISH );

国际化 Java 应用程序

            System.out.println( res.getString( key ) );

国际化 Java 应用程序

        }

国际化 Java 应用程序

        catch ( MissingResourceException exp )

国际化 Java 应用程序

        {

国际化 Java 应用程序

            exp.printStackTrace();

国际化 Java 应用程序

        }

国际化 Java 应用程序

    }

国际化 Java 应用程序

}

运行结果:

再见

bye

2、PropertyResourceBundle Example

2.1 英文配置文件({project}/classes/resources/rb_en.properties)

国际化 Java 应用程序

# rb_en.properties

国际化 Java 应用程序
国际化 Java 应用程序

CHG = change

国际化 Java 应用程序

MSG = message

国际化 Java 应用程序

BYE = bye

2.2 中文配置文件({project}/classes/resources/rb_zn_CN.properties)

国际化 Java 应用程序

# rb_zn_CN.properties

国际化 Java 应用程序
国际化 Java 应用程序

CHG = 修改

国际化 Java 应用程序

MSG = 消息

国际化 Java 应用程序

BYE = 再见

2.3 测试类

国际化 Java 应用程序
国际化 Java 应用程序

package  org.anymobile.test;

国际化 Java 应用程序
国际化 Java 应用程序

import  java.util.Locale;

国际化 Java 应用程序

import  java.util.MissingResourceException;

国际化 Java 应用程序

import  java.util.ResourceBundle;

国际化 Java 应用程序
国际化 Java 应用程序
国际化 Java 应用程序

public   class  MyPropResourceBundle

国际化 Java 应用程序

{

国际化 Java 应用程序

    public static void main( String[] args )

国际化 Java 应用程序

    {

国际化 Java 应用程序

        String baseName = "resources.rb";

国际化 Java 应用程序

        String key = "CHG";

国际化 Java 应用程序
国际化 Java 应用程序

        try

国际化 Java 应用程序

        {

国际化 Java 应用程序

//            ResourceBundle res = ResourceBundle.getBundle( baseName, Locale

国际化 Java 应用程序

//                    .getDefault() );

国际化 Java 应用程序

            ResourceBundle res = ResourceBundle.getBundle( baseName, new Locale("zh","CN","WINDOWS") );

国际化 Java 应用程序

            System.out.println( key + ": " + res.getString( key ) );

国际化 Java 应用程序
国际化 Java 应用程序

            res = ResourceBundle.getBundle( baseName, Locale.ENGLISH );

国际化 Java 应用程序

            System.out.println( key + ": " + res.getString( key ) );

国际化 Java 应用程序

        }

国际化 Java 应用程序

        catch ( MissingResourceException exp )

国际化 Java 应用程序

        {

国际化 Java 应用程序

            exp.printStackTrace();

国际化 Java 应用程序

        }

国际化 Java 应用程序

    }

国际化 Java 应用程序

}

运行结果:

CHG: 改变

CHG: change

另外,为了不致于在程序中产生乱码,可以通过jdk自带的native2ascii程序将.properties文件从本地编码转换成unicode编号格式的数据文件,为避免读取时因编码问题而出现乱码,可以先编写一个src.txt文件,然后执行指令:native2ascii src.txt dest.properties。转换后,如“中国”的unicode字符码为“/u4e2d/u56fd”。

如果需要将unicode恢复成原编码,可以执行指令:native2ascii -reverse dest.file src.file。

每次必须运行native2ascii方法比较繁琐,实际开发中,可以通过Apache Ant的native2Ascii任务进行批量转码。如:<native2ascii encoding="GBK" src="${src}" dest="${build}"/>

3、Spring 的消息国际化

org.springframework.context.ApplicationContext继承了org.springframework.context.MessgeResource接口,通过起getMessage()的各个版本读取文字消息的资源文件,从而实现消息国际化。

public interface MessageSource

{

String getMessage(String code, Object[] args, String defaultMessage, Locale locale);

}

参考资料:

Java 2 SDK Document

How to internationalize Java applications(Sun) http://java.sun.com/docs/books/tutorial/i18n/index.html

ISO Language Code    http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt

ISO Country Code      http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html