📅  最后修改于: 2023-12-03 15:02:04.193000             🧑  作者: Mango
Java国际化,是指将一个软件产品做成适合在不同语言环境下使用的形式。如英文版软件变成中文版,而且还能够适应日文、法文、俄文等其他语言环境,这就是 Java 国际化。
Java 国际化一般使用 java.util 包中的 ResourceBundle 类,其实现方式相对比较简单明了。
定义资源文件
Java国际化的第一步要做的是定义语言资源文件。通常的资源文件格式为:基础名称_语言_国别.properties,其中基础名称是必须的,语言和国别是可选的。
例:
基础名称为 message,语言为 en,国别为 US,则文件名应该为 message_en_US.properties。
确定 Locale 对象
Java 中的 Locale 对象是用来表示特定的国家和地区的。
在资源文件中添加键-值对,如:
hello=Hello, {0}!
在程序中,使用 ResourceBundle.getBundle() 方法并指定对应的 Locale 来获取 ResourceBundle 对象。
ResourceBundle bundle = ResourceBundle.getBundle("message", new Locale("en", "US"));
获取资源文件的值
通过 ResourceBundle 对象的 getString() 方法获取资源文件中对应键的值。
String hello = bundle.getString("hello");
String formatted = MessageFormat.format(hello, "World");
System.out.println(formatted);
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
public class InternationalizationDemo {
public static void main(String[] args) {
ResourceBundle bundle = ResourceBundle.getBundle("message", new Locale("en", "US"));
String hello = bundle.getString("hello");
String formatted = MessageFormat.format(hello, "World");
System.out.println(formatted);
}
}
在使用 ResourceBundle 实现国际化时,需要在程序中编写一些代码,最好包装成一个通用类。Java 提供了一种机制,MessageSource 接口和 ResourceBundleMessageSource 类,来实现处理国际化信息的功能。
编写 Resource(资源)接口类
import org.springframework.context.MessageSourceResolvable;
public interface Resource extends MessageSourceResolvable {
}
编写 ResourceFactory(资源工厂)接口类
import org.springframework.context.MessageSource;
import java.util.Locale;
public interface ResourceFactory {
/**
* 获取指定 Locale 的资源对象。
* @param locale 服务器 Locale 对象
* @return 资源对象。
*/
MessageSource getMessageSource(Locale locale);
}
在 getMessageSource(Locale) 方法中,获取指定 Locale 的 ResourceBundle,并返回一个 ResourceBundleMessageSource 对象。
@Override
public MessageSource getMessageSource(Locale locale) {
final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename(BASENAME);
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(86400); // 过期时间设置为 24 小时
messageSource.setFallbackToSystemLocale(false);
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setLocale(locale);
return messageSource;
}
编写实现 Resource 接口的枚举类
枚举类中存储资源文件中的键,同时定义 getMessageSourceKey() 方法,用于返回对应的消息源键值。
public enum ResourceImpl implements Resource {
HELLO("message.hello");
private final String messageKey;
ResourceImpl(String messageKey) {
this.messageKey = messageKey;
}
@Override
public String[] getCodes() {
return new String[]{messageKey};
}
@Override
public Object[] getArguments() {
return new Object[0];
}
@Override
public String getDefaultMessage() {
return messageKey;
}
String getMessageSourceKey() {
return this.name().toLowerCase()
.replace('_', '.');
}
}
编写一个名为 message.properties 的资源文件。该文件中包含支持各个语言的字符串,并且为每条字符串指定一个名称。
message.hello=Hello, {0}!
在业务代码中使用
使用 Spring 的 ApplicationContext 接口加载 Spring 容器,并调用 getMessage() 方法来获取特定区域的消息。
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getMessage(ResourceImpl.HELLO.getMessageSourceKey(), new Object[] {"World"}, new Locale("en", "US")));
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(context.getMessage(ResourceImpl.HELLO.getMessageSourceKey(), new Object[] {"World"}, new Locale("en", "US")));
}
}
Java 国际化是指将一个软件产品做成适合在不同语言环境下使用的形式。所谓国际化,实际上就是在不修改软件内部逻辑的情况下,通过重载软件的资源、平台各种配置等信息,以实现让软件在不同的地理区域和语言环境下运行的一种技术方案。
通过 ResourceBundle 和 Spring MessageSource 实现 Java 国际化,使得我们可以在程序中轻松实现对多种语言环境的支持。