Рубрики
Без рубрики

Руководство по ресурсуBundle

Всегда сложно поддерживать и расширять многоязычные приложения. В этой статье рассказывается о том, как использовать ResourceBundle, чтобы справиться с разновидностями, которые приходят, когда вам нужно предоставить то же содержание для различных культур.

Автор оригинала: baeldung.

1. Обзор

Многие разработчики программного обеспечения, в течение своей профессиональной карьеры, сталкиваются с возможностью разработки многоязычных систем или приложений. Они обычно предназначены для конечных пользователей из разных регионов или различных языковых областей.

Всегда сложно поддерживать и расширять эти приложения. Способность работать с различными конкретными данными локализации в то же время, как правило, имеет решающее значение. Изменение данных приложения должно быть как можно более простым без необходимости компенсации. Вот почему мы обычно избегаем жесткого кодирования меток или названий кнопок.

К счастью, мы можем сделать банк на Java, который предоставляет нам этот класс, который помогает нам решить все проблемы, упомянутые выше.

Проще говоря, РесурсБундл позволяет нашему приложению загружать данные из различных файлов, содержащих локальные данные.

1.1. Ресурсбанки

Первое, что мы должны знать, что все файлы в один пакет ресурсов должен быть в одном пакете/каталоге и иметь общее базовое название . Они могут иметь локальные суффиксы, указывающие на язык, страну или платформу, отделенную символом подчеркивания.

Важно, чтобы мы могли в приложении код страны, если уже есть языковой код, или платформы, если язык и коды стран присутствуют.

Рассмотрим имена файлов на примере:

  • ПримерРесурс
  • ExampleResource_en
  • ExampleResource_en_US
  • ExampleResource_en_US_UNIX

Файл по умолчанию для каждого пакета данных всегда один без каких-либо суффиксов – ПримерРесурс . Как Есть два подкласса РесурсБанк : НедвижимостьРесурсБанкдл и ListResourceBundle , мы можем взаимозаменяемо хранить данные в файлах свойств, а также Java файлов.

Каждый файл должен иметь локальное имя и надлежащее расширение файла например, ExampleResource_en_US.свойства или Example_en.java .

1.2. Файлы недвижимости – PropertyResourceBundle

Файлы свойств представлены НедвижимостьРесурсБанкдл. Они хранят данные в виде чувствительных к делу пар ключевых значений.

Давайте проанализируем файл свойства образца:

# Buttons
continueButton continue
cancelButton=cancel

! Labels
helloLabel:hello

Как мы видим, существует три различных стиля определения пар ключевых значений.

Все они эквивалентны, но первый, пожалуй, самый популярный среди Java Программистов. Стоит знать, что мы можем поставить комментарии в файлах свойств, а также. Комментарии всегда начинаются с # или ! .

1.3. Файлы Java – ListResourceBundle

Прежде всего, для того, чтобы хранить наши языковые данные, нам необходимо создать класс, который расширяет ListResourceBundle и переопределяет getContents () метод. Конвенция имени класса такая же, как и для файлов свойств.

Для каждого Локале, нам нужно создать отдельный класс Java.

Вот пример класса:

public class ExampleResource_pl_PL extends ListResourceBundle {

    @Override
    protected Object[][] getContents() {
        return new Object[][] {
          {"currency", "polish zloty"},
          {"toUsdRate", new BigDecimal("3.401")},
          {"cities", new String[] { "Warsaw", "Cracow" }} 
        };
    }
}

Java файлы имеют одно важное преимущество по сравнению с файлами свойств, которая является возможность проведения любого объекта, который мы хотим – не только Строки.

С другой стороны, каждая модификация или введение нового класса Java для конкретных локалов требует перекомпиляции приложения, в то время как файлы свойств могут быть расширены без каких-либо дополнительных усилий.

2. Использование комплектов ресурсов

Мы уже знаем, как определить пакеты ресурсов, поэтому мы готовы использовать его.

Рассмотрим короткий фрагмент кода:

Locale locale = new Locale("pl", "PL");
ResourceBundle exampleBundle = ResourceBundle.getBundle("package.ExampleResource", locale);

assertEquals(exampleBundle.getString("currency"), "polish zloty");
assertEquals(exampleBundle.getObject("toUsdRate"), new BigDecimal("3.401")); 
assertArrayEquals(exampleBundle.getStringArray("cities"), new String[]{"Warsaw", "Cracow"});

Во-первых, мы можем определить нашу Локале , если мы не хотим использовать по умолчанию один.

После этого назовем статический заводской метод РесурсБанк . Мы должны пройти имя расслоения с его пакетом/каталогом и локале в качестве параметров.

Там также заводской метод, который требует только имя расслоения, если локале по умолчанию в порядке. Как только у нас есть объект, мы можем получить значения по их ключам.

Кроме того, пример показывает, что мы можем использовать getString (Струнный ключ) , getObject (Струнный ключ), и getStringArray (Струнный ключ) чтобы получить ценности, которые мы хотим.

3. Выбор правильного ресурса комплекта

Если мы хотим использовать ресурс расслоения, важно знать, как Ява выбирает файлы расслоения.

Давайте представим, что мы работаем с приложением, которое нуждается в этикетках на польском языке, но ваш СПМ локале Locale.US .

В начале приложение будет искать файлы в classpath подходит для локалов вы просите. Она начинается с самого конкретного названия, то есть с платформы, страны и языка.

Затем, он идет к более общим. Если нет матча, он падает обратно в локале по умолчанию без проверки платформы на этот раз.

В случае не совпадают, он будет пытаться читать по умолчанию расслоение. Все должно быть ясно, когда мы смотрим на порядок выбранных имен файлов:

  • Label_pl_PL_UNIX
  • Label_pl_PL
  • Label_pl
  • Label_en_US
  • Label_en
  • ярлык

Мы должны иметь в виду, что каждое имя представляет как .java и .свойства файлов, но первый имеет приоритет над последним. Когда нет подходящего файла, Пропавшие без вестиРесурсЭксцепция брошен.

4. Наследование

Еще одним преимуществом концепции пакетов ресурсов является наследование имущества. Это означает, что пары ключевых значений, включенные в менее специфические файлы, наследуются теми, которые выше в дереве наследования.

Предположим, что у нас есть три файла свойств:

#resource.properties
cancelButton = cancel

#resource_pl.properties
continueButton = dalej

#resource_pl_PL.properties
backButton = cofnij

Ресурсный пакет, извлеченный для Locale (“пл”, “PL”) вернет все три ключа/значения в результате. Стоит упомянуть, нет отступить к умолчанию локале расслоение в том, что касается наследования имущества.

Более того, ListResourceBundles и НедвижимостьРесурсБанкдлс не в той же иерархии.

Так что, если файл свойства находится в classpath, то пары ключевых значений наследуются только из файлов свойств. То же правило распространяется и на файлы Java.

5. Настройка

Все, что мы узнали выше, было о реализации по умолчанию РесурсБанк . Тем не менее, есть способ изменить его поведение.

Мы делаем это, расширяя РесурсBoundle.Control и переопределять его методы.

Например, мы можем изменить время хранения значений в кэше или определить состояние перезарядки кэша.

Для лучшего понимания подготовим в качестве примера короткий метод:

public class ExampleControl extends ResourceBundle.Control {

    @Override
    public List getCandidateLocales(String s, Locale locale) {
        return Arrays.asList(new Locale("pl", "PL"));
    }
}

Целью этого метода является изменение способа выбора файлов в классной тропе. Как мы видим, ПримерКонтроль вернется только польский Локале , независимо от того, что по умолчанию или Локале есть.

6. UTF-8

Так как есть еще много приложений, использующих JDK 8 или старые версии, стоит знать, что до Java 9 ListResourceBundles было еще одно преимущество над НедвижимостьРесурсБанкдлс . Поскольку Java-файлы могут хранить объекты String, они могут удерживать любой символ, поддерживаемый UTF-16 кодировка.

Напротив, НедвижимостьРесурсБанкдл загружает файлы по умолчанию с помощью ISO 8859-1 кодирование, которое имеет меньше символов, чем UTF-8 (вызывает проблемы для наших примеров польского языка).

Для того, чтобы сохранить символы, которые находятся за пределами UTF-8 , мы можем использовать Родной-ASCII преобразователь – native2ascii . Он преобразует все символы, которые не соответствуют ISO 8859-1, кодируя их на Зукскс нотация.

Вот пример команды:

native2ascii -encoding UTF-8 utf8.properties nonUtf8.properties

И давайте посмотрим, как выглядят свойства до и после изменения кодирования:

#Before
polishHello=cześć

#After
polishHello=cze\u015b\u0107

К счастью, это неудобство больше не существует в Java 9. СПМ читает файлы свойств в UTF-8 кодирования, и нет никаких проблем в использовании не-латинских символов.

7. Заключение

КомплектРесурс содержит многое из того, что нам нужно для разработки многоязычного приложения. Функции, которые мы рассмотрели сделать манипуляции различных местах довольно проста.

Мы также избегаем значений жесткого кодирования, что позволяет нам расширить поддерживаемые Локалес просто добавляя новые Локале файлы, позволяющие плавно модифицировать и поддерживать наше приложение.

Как всегда, образец кода доступен в более на GitHub .