Класс ResourceBundle

Класс ResourceBundle вместе с классом Locale лежит в основе процесса интернационализации в языке Java.

Класс ResourceBundle предназначен для чтения данных из текстовых файлов свойств (расширение - properties). Каждый отдельный файл с расширением properties содержит информацию для отдельной локали.

В файлах свойств (*.properties) информация должна быть организована по принципу:

#Комментарий
group1.key1 = value1
group1.key2 = value2
group2.key1 = value3…

Например:

label.button = submit
label.field = login
message.welcome = Welcome!

или

label.button = принять
label.field = логин
message.welcome = Добро пожаловать!

Рассмотрим правила выбора имени для properties файлов. Выбираем базовое имя для группы properties файлов. Например text. Добавляем к базовому имени через пробел код языка (uk) и код страны (UA).

Следующий список показывает возможный набор соответствующих ресурсов с базовым именем:
text.properties
text_ru_RU.properties
text_uk_UA.properties
text_fr_CA.properties

Чтобы выбрать определенный объект ResourceBundle, следует вызвать один из статических перегруженных методов getBundle(параметры).

Следующий фрагмент выбирает text объекта ResourceBundle для объекта Locale, который соответствует французскому языку и стране Канада:

Locale locale = new Locale("fr", "CA");
ResourceBundle rb = ResourceBundle.getBundle("text", locale);

Если объект ResourceBundle для заданного объекта Locale не существует, то метод getBundle() извлечет наиболее общий.

Если общее определение файла ресурсов не задано, то метод getBundle() генерирует исключительную ситуацию MissingResourceException. Чтобы это не произошло, необходимо обеспечить наличие базового файла ресурсов без суффиксов, а именно: text.properties в дополнение к частным случаям вида: 
text_en_US.properties
text_ru_RU.properties.

Пусть базовое имя ресурса baseName, и ресурс нам нужен для fr, CA. Locale по умолчанию определена через uk, UA. Мы вызываем ResourceBundle.getBundle(baseName, canadaLocale). В каком порядке будет организован поиск в properties файлах? Формируется следующий список строк (так называемые кандидаты в имена пакетов):

  1. baseName + "_"+ fr + "_" + CA
  2. baseName + "_"+ fr
  3. baseName + "_"+ uk + "_" + UA
  4. baseName + "_"+ uk
  5. baseName

Рассмотрим пример использования класса ResourceBundle:

import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;

public class ResourceBundleDemo1 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        printInfo("", "");
        printInfo("en", "US");
        printInfo("uk", "UA");
    }

    private static void printInfo(String language, String country)
            throws UnsupportedEncodingException {
        Locale current = new Locale(language, country);
        ResourceBundle rb = ResourceBundle.getBundle("text", current);
        String s1 = rb.getString("str1");

        System.out.println(s1);
        String s2 = rb.getString("str2");
        System.out.println(s2);
        System.out.println();
    }
}

В классе ResourceBundle определен ряд полезных методов:

  1. getKeys() - возвращает объект Enumeration, который применяется для последовательного обращения к элементам.
  2. keySet() – возвращает множество Set всех ключей.
  3. getString(String key) - извлекается конкретное значение по конкретному ключу.
  4. boolean containsKey(String key) - проверить наличие ключа в файле.

В следующем примере используется метод keySet() класса ResourceBundle:

public class ResourceBundleDemo2 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        printInfo("", "");

        printInfo("en", "US");
        printInfo("uk", "UA");
    }

    private static void printInfo(String language, String country)
            throws UnsupportedEncodingException {
        Locale current = new Locale(language, country);
        ResourceBundle rb = ResourceBundle.getBundle("text", current);
        for (String key : rb.keySet()) {
            String value = rb.getString(key);
            System.out.println(value);
        }
        System.out.println();
    }
}
Read also:
Comments