国际化是指应用程序运行时,可根据客户端请求来自的国家/地区、语言的不同而显示不同的界面。例如,如果请求来自于中文操作系统的客户端,则应用程序中的各种提示信息错误和帮助等都是用中文。
Java程序的国际化思路是将程序中的标签、提示等信息放在资源文件中,程序需要支持哪些国家、语言环境,就对应提供相应的资源文件 。资源文件时key-value对,每个资源文件中的key时不变的,但是value则随不同的国家、语言而改变。
Java程序国际化的思路图:
Java程序的国际化主要通过如下三个类完成:
- java.util.ResourceBundle:用于加载国家、语言资源包
- java.util.Locale:用于封装特定的国家/区域、语言环境
- java.text.MessageFormat:用于格式化带占位符的字符串。
范例:定义一个Messages.properties
- 如果保存的是中文信息,那么必须将其转换为UNICODE编码
info=中华人民共和国
info=\u4E2D\u56FD\u4EBA\u6C11\u5171\u548C\u56FD
info就是key,可以根据key取得对应的value。
如果要读取资源文件的信息使用java.util.ResourceBundle
类,这是一个抽象类,但是这个类的内部也提供一个static方法用于取得本类对象:
- 根据当前语言环境取出:
public static final ResourceBundle getBundle(String baseName)
- 设置指定语言环境:
public static final ResourceBundle getBundle(String baseName, Locale locale)
当取得ResourceBundle类对象之后可以通过以下的方法读取数据:
- 简单读取:
public final String getString(String key)
java.text是专门负责国际化处理的程序包,用于处理占位字符串的类,就在这个包里面。
- 格式化文本:
public static String format(String pattern, Object... arguments)
范例:读取普通文本
import java.util.ResourceBundle;
public class I18NDemo {
public static void main(String[] args) {
ResourceBundle rb = ResourceBundle.getBundle("Messages");
System.out.println(rb.getString("info"));
}
}
但是很多时候配置文件里面的数据时候改变的,例如:
范例:修改Messages.properties文件
wel.msg = 欢迎{0}光临,现在时间是:{1}!
其中{0} {1}都是占位符
范例:设置读取的可变内容
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.ResourceBundle;
public class I18NDemo {
public static void main(String[] args) {
ResourceBundle rb = ResourceBundle.getBundle("Messages");
String str = rb.getString("wel.msg");
System.out.println(MessageFormat.format(str, "张三" ,
new SimpleDateFormat("yyyy-MM--dd").format(new Date())));
}
}
国际化程序应该要根据所在的国家不同可以显示不同的内容,可是只提供了一个资源文件,怎么进行不同语言的显示呢?
java.util.Locale保存的是国家的区域和语言编码:
- 中国:zh_CN;
- 美国:en_US;
可以在定义资源文件的时候加上指定的语言编码,例如:
范例:
定义中文的资源文件—-Messages_zh_CN.properties
定义英文的资源文件—-Messages_en_US.properties
设置的baseName一定要是Messages,所有的语言编码由Locale类设置,Locale类里提供有以下方法:
- 构造方法:
public Locale(String language, String country)
- 取得当前语言环境:
public static Locale getDefault()
范例:读取配置文件
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
public class I18NDemo {
public static void main(String[] args) {
Locale loc = new Locale("en" , "US");
ResourceBundle rb = ResourceBundle.getBundle("Messages" , loc);
String str = rb.getString("wel.msg");
System.out.println(MessageFormat.format(str, "Qianjin" ,
new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
}
}
如果已经存在特定的国家语言资源文件,就不会读取公共的资源文件了。
总结
- 资源文件:文件名称每个单词字母大写,后缀必须是”*.properties”;
- 通过ResourceBundle类可以读取在指定的CLASSPATH下的资源文件,读取时不需要输入文件后缀;动态的占位文本格式化:MessageFormat.
- Locale类用于指定读取的资源文件的语言环境。