📜  Java国际化教程(1)

📅  最后修改于: 2023-12-03 15:02:04.193000             🧑  作者: Mango

Java国际化教程

简介

Java国际化,是指将一个软件产品做成适合在不同语言环境下使用的形式。如英文版软件变成中文版,而且还能够适应日文、法文、俄文等其他语言环境,这就是 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 国际化,使得我们可以在程序中轻松实现对多种语言环境的支持。