Struts 2 的国际化(一)

 

一、 程序国际化简介

 

国际化是指应用程序运行时,可根据客户端请求来自的国家/地区、语言的不同而显示不同的界面

 

1.1 程序国际化的意义

 

      全球化软件,意味着同一种版本的产品能够容易地适用于不同地区的市场。软件全球化意味着国际化和本地化。

      国际化是指应用程序运行时,可根据客户端请求来自的国家/地区、语言的不同而显示不同的界面。

      国际化的英文单词是 Internationalization ,简称 I18N ,I 是首字母,18 表示省略当中的字母个数,N 代表最有一个字母

      一个国际化支持很好的应用,会随着在不同区域使用时,呈现出本地语言提示。这个过程被成为 Localization,即本地化。简称 L10N

      java 内核基于 UNICODE 2.1 编码集,提供了对不同国家,不同语言的支持,它已经具有国际化和本地化的特征和 API,因此 java 程序的国际化相对比较简单。

 

1.2 Java 国际化的思路


    Java 程序国际化思路是 将程序中的标签、提示等信息放在资源文件中,程序需要支持的国家/语言环境,则必须提供对应的资源文件。资源文件是 key-value 对,每个资源文件中的 key 是不变的,但 value 则随不同国家/语言变化

 

   j ava 程序的国际化主要通过如下 3 个类完成

 java.util.ResourceBundle : 用于加载一个资源包

 java.util.Locale : 对应一个特定的国家/区域、语言环境

 java.text.MessageFormat : 用于将消息格式化

 

   为了实现国际化,必须先提供程序所需要的资源文件。资源文件内容是很多 key-value 对。

   资源文件的命名可以有如下 3 种形式

 baseName_language_country.properties

 baseName_language.properties

 baseName.properties

 

  其中 baseName 是资源文件的基本名,用户可以自由定义,而 languagecountry 都不可随意变化,必须是 java 所支持的语言和国家

 

 

1.3 Java 支持的语言和国家

 

  事实上,java 不可能支持所有国家和语言,如需要获取 java 所支持的语言和国家,可调用 Locale 类的 getAvailableLocale() 方法获取,该方法返回一个 Locale 数组,该数组包含 java 所支持的语言和国家

 

LocaleList.java

import java.util.*;

public class LocaleList
{
	public static void main(String[] args) 
	{
		//返回Java所支持的全部国家和语言的数组
		Locale[] localeList = Locale.getAvailableLocales();
		//遍历数组的每个元素,依次获取所支持的国家和语言
		for (int i = 0; i < localeList.length ; i++ )
		{
			//打印出所支持的国家和语言
			System.out.println(localeList[i].getDisplayCountry()
				+ "=" + localeList[i].getCountry()	+ " "
				+ localeList[i].getDisplayLanguage() + "="
				+ localeList[i].getLanguage());
		}
	}
}
 

通过该程序,就可以获得 java 程序所支持的国家/语言环境。

 

 

1.4 完成程序国际化

 

如有如下简单程序:

public class RawHello
{
	public static void main(String[] args)
	{
		System.out.println("Hello World");
	}
}
 

   为了让该程序支持国际化,则肯定不能让程序直接输出 "Hello World" ,为了让程序可以输出不同的字符串,此处绝对不能使用这种字符串常量。

   为了让上面输出的字符串常量可以改变,我们将需要输出的各种字符串 (不同国家/语言环境对应不同的字符串)定义在资源包中。

 

为上面程序提供如下 2 个文件

 mess_zh_CN.properties

#资源文件的内容是 key-value 对
hello=您好!

 mess_en_US.properties

hello=Hello World!
 

对于包含非西欧字符的资源文件,Java 提供了一个工具来处理该文件: native2ascii ,这个工具可以在 %JAVA_HOME%/bin 路径下找到。

使用 格式如下

native2ascii  源资源文件  目的资源文件

 如果我们在命令窗口输入如下指令:

native2ascii mess_zh_CN.properties aa.properties

   上面命令将生成一个 aa.properties 文件,该文件才是我们需要的资源文件。该文件看上去包含很多乱码,其实是非西欧字符的 UNICODE 编码方式,这完全正常。将该文件重命名为 mess_zh_CN.properties 即可。

 

Hello.java

import java.util.*;

public class Hello {
    public static void main(String[] args) {
        // 取得系统默认的国家/语言环境
        Locale myLocale = Locale.getDefault();
        // 根据指定国家/语言环境加载资源文件
        ResourceBundle bundle = ResourceBundle.getBundle("mess", myLocale);
        // 打印从资源文件中取得的消息
        System.out.println(bundle.getString("hello"));
    }
}

 

Java 国际化的关键类是 ResourceBundle ,有如下方法:

 

● getBundle(String baseName, Locale locale);

    上面方法将根据 Locale 加载资源文件,Locale 代表一个国家/语言。

例如:

● ResourceBundle bundle = ResourceBundle.getBundle("mess", myLocale);

    上面代码会加载 baseName 为 mess 的系列资源文件的其中之一,到底加载哪个,取决于 myLocale,对于简体中文,则加载 mess_zh_CH.properties.

 

 

1.5 使用 MessageFormat 处理带占位符的消息

 

MyResource_en_US.properties

msg=Hello,{0}!Today is {1}.

 MyResource_zh_CN.properties

msg=你好,{0}!今天是{1}。

 

如上,我们需要使用参数为 {0} ,{1} 两个占位符赋值

 

此时需要使用 MessageFormat 类,方法:

● format(String pattern , Object... values) : 返回后面的多个参数值填充前面的 pattern 字符串,其中 pattern 字符串就是一个带有占位符的字符串

 

PlaceHolderMsg.java

import java.util.*;
import java.text.*;

public class PlaceHolderMsg {
    public static void main(String[] args) {
        // 定义一个Locale变量
        Locale currentLocale = null;
        // 如果运行程序指定了两个参数
        if (args.length == 2) {
            // 使用运行程序的两个参数构造Locale实例
            currentLocale = new Locale(args[0], args[1]);
        } else {
            // 否则直接使用系统默认的Locale
            currentLocale = Locale.getDefault();
        }

        // 根据Locale加载语言资源
        ResourceBundle bundle = ResourceBundle.getBundle("MyResource",
            currentLocale);

        // 取得已加载的语言资源文件中msg对应消息
        String msg = bundle.getString("msg");

        // 使用MessageFormat为带占位符的字符串传入参数
        System.out.println(MessageFormat.format(msg, "yeeku", new Date()));
    }
}
 

如果程序不能找到对应的资源文件,系统会如下搜索:(假设是简体中文环境)

 

MyResource_zh_CN.properties

    如果没有找到,即搜索如下文件:

MyResource_zh.properties

    如果没有找到,即搜索如下文件:

MyResource.properties

    如果上面 3 个文件都找不到,则系统会出现异常。

 

 

1.6 使用类文件代替资源文件

 

使用 java 文件来代替资源文件,必须满足如下条件

 类的名字必须为 baseName_language_country ,这与属性文件的命名相似

  类必须继承 ListResourceBundle,并重写 getContents() 方法,返回 Object 数组,该数组的每个项都是 key-value对


MyResource_zh_CN.java

import java.util.*;

public class MyResource_zh_CN extends ListResourceBundle {
    // 定义资源
    private final Object myData[][] = {{"msg", "类文件消息:{0},您好!今天是{1}"}};

    // 重写方法getContents()
    public Object[][] getContents() {
        // 该方法返回资源的key-value对
        return myData;
    }
}
 

上面文件如果在简体中文环境下,可以代替 MyResource_zh_CN.properties

 

如果系统中存在资源文件、类文件,系统将以类文件为主,而不会调用资源文件

 

对于简体中文的 Locale ResourceBundle 搜索资源的顺序 是:

 baseName_zh_CN.class

 baseName_zh_CN.properties

 baseName_zh.class

 baseName_zh.properties

 baseName.class

 baseName.properties

 

系统按上面的顺序搜索资源文件,如果前面的文件不存在,才会使用下一个。如果一直找不到对应的文件,系统将抛出异常

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值