Пакет сообщений представляет собой набор файлов свойств с именами вида messages{_XX}.properties
, расположенных в одном Java-пакете. Суффикс XX
определяет язык, для которого в данном файле содержатся сообщения, и соответствует коду языка в Locale.getLanguage()
. Возможно также использование остальных атрибутов Locale
, например, country
. В этом случая файл пакета будет иметь вид messages{_XX_YY}.properties
. Один из файлов пакета может быть без суффикса языка - это файл по умолчанию. Именем пакета сообщений считается имя Java-пакета, в котором расположены файлы пакета.
Рассмотрим пример:
/com/abc/sales/gui/customer/messages.properties /com/abc/sales/gui/customer/messages_fr.properties /com/abc/sales/gui/customer/messages_ru.properties
Данный пакет состоит из 3-х файлов - один для русского языка, один для французского, и один по умолчанию. Имя пакета - com.abc.sales.gui.customer
Файлы сообщений содержат пары ключ-значение, где ключ - это идентификатор сообщения, на который ссылается код приложения,
а значение - само сообщение на языке данного файла. Правила задания пар аналогичны правилам файлов свойств java.util.Properties
, со следующими особенностями:
-
Кодировка файла - обязательно
UTF-8
-
Поддерживается включение других пакетов сообщений с помощью ключа
@include
, в том числе нескольких сразу - перечислением через запятую. При этом если некоторый ключ сообщения встречается и во включаемом пакете, и в текущем, будет использовано сообщение из текущего. Пример включения пакетов:@include=com.haulmont.cuba.web, com.abc.sales.web someMessage=Some Message ...
Получение сообщений из пакетов производится с помощью методов интерфейса
Messages
по следующим правилам:
-
Сначала производится поиск в конфигурационном каталоге приложения
-
Ищется файл
messages_XX.properties
в каталоге, задаваемом именем пакета сообщений, гдеXX
- код требуемого языка -
Если такого файла нет, в этом же каталоге ищется файл по умолчанию
messages.properties
-
Если найден или файл нужного языка, или файл по умолчанию, он загружается вместе со всеми
@include
, и в нем ищется ключ сообщения -
Если файл не найден, либо нужный ключ в нем отсутствует, производится смена каталога на родительский, и процедура поиска повторяется. И так до достижения корня конфигурационного каталога.
-
-
Если в конфигурационном каталоге сообщение не найдено, производится поиск в classpath по такому же алгоритму.
-
На клиентском уровне, если сообщение не найдено на предыдущих шагах, отправляется запрос на Middleware, и сообщение ищется там аналогичным способом.
-
Если сообщение найдено, оно кэшируется и возвращается. Если не найдено - кэшируется факт отсутствия сообщения и возвращается ключ, который был передан для поиска. Таким образом, сложная процедура поиска выполняется только один раз, в дальнейшем результат загружается из локального для блока приложения кэша.
Рекомендуется организовывать пакеты сообщений следующим образом:
-
Если приложение не предполагает интернационализации, то можно не использовать пакеты и включать строки сообщений прямо в код приложения, либо пользоваться файлами по умолчанию
messages.properties
для отделения ресурсов от кода. -
Если приложение интернациональное, логично файлы по умолчанию использовать для языка основной аудитории приложения, либо для английского языка. Именно сообщения из файлов по умолчанию будут показаны пользователю, если сообщений для нужного языка не найдено.