Локализиране на съобщения за изключения в Java

1. Общ преглед

Изключенията в Java се използват, за да сигнализират, че нещо се е объркало в дадена програма. В допълнение към изхвърлянето на изключението, можем дори да добавим съобщение, за да предоставим допълнителна информация.

В тази статия ще се възползваме от метода getLocalizedMessage , за да предоставим съобщения за изключения както на английски, така и на френски език.

2. Пакет ресурси

Имаме нужда от начин за търсене на съобщения, използвайки messageKey, за да идентифицираме съобщението и Locale, за да идентифицираме кой превод ще предостави стойността за messageKey . Ще създадем прост клас за абстрактен достъп до нашия ResourceBundle за извличане на преводи на английски и френски съобщения:

public class Messages { public static String getMessageForLocale(String messageKey, Locale locale) { return ResourceBundle.getBundle("messages", locale) .getString(messageKey); } } 

Нашият клас Messages използва ResourceBundle за зареждане на файловете със свойства в нашия пакет, който е в основата на нашия път на класа. Имаме два файла - един за нашите английски съобщения и един за нашите френски съобщения:

# messages.properties message.exception = I am an exception.
# messages_fr.properties message.exception = Je suis une exception.

3. Локализиран клас на изключение

Подкласът ни за изключения ще използва локала по подразбиране, за да определи кой превод да използваме за нашите съобщения. Ще получим локала по подразбиране с помощта на Locale # getDefault .

Ако приложението ни се изпълняваше на сървър, щяхме да използваме заглавките на HTTP заявката, за да идентифицираме локала, който да използваме, вместо да зададем по подразбиране. За тази цел ще създадем конструктор, който да приеме локал.

Нека създадем нашия подклас за изключения . За това можем да разширим RuntimeException или Exception . Нека разширим изключението и да заменим getLocalizedMessage :

public class LocalizedException extends Exception { private final String messageKey; private final Locale locale; public LocalizedException(String messageKey) { this(messageKey, Locale.getDefault()); } public LocalizedException(String messageKey, Locale locale) { this.messageKey = messageKey; this.locale = locale; } public String getLocalizedMessage() { return Messages.getMessageForLocale(messageKey, locale); } } 

4. Събиране на всичко заедно

Нека създадем някои модулни тестове, за да проверим дали всичко работи. Ще създадем тестове за преводи на английски и френски, за да потвърдим предаването на персонализиран Locale до изключението по време на строителството:

@Test public void givenUsEnglishProvidedLocale_whenLocalizingMessage_thenMessageComesFromDefaultMessage() { LocalizedException localizedException = new LocalizedException("message.exception", Locale.US); String usEnglishLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(usEnglishLocalizedExceptionMessage).isEqualTo("I am an exception."); } @Test public void givenFranceFrenchProvidedLocale_whenLocalizingMessage_thenMessageComesFromFrenchTranslationMessages() { LocalizedException localizedException = new LocalizedException("message.exception", Locale.FRANCE); String franceFrenchLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(franceFrenchLocalizedExceptionMessage).isEqualTo("Je suis une exception."); }

Нашето изключение може да използва и локала по подразбиране . Нека създадем още два теста, за да проверим дали функцията по подразбиране Locale работи:

@Test public void givenUsEnglishDefaultLocale_whenLocalizingMessage_thenMessageComesFromDefaultMessages() { Locale.setDefault(Locale.US); LocalizedException localizedException = new LocalizedException("message.exception"); String usEnglishLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(usEnglishLocalizedExceptionMessage).isEqualTo("I am an exception."); } @Test public void givenFranceFrenchDefaultLocale_whenLocalizingMessage_thenMessageComesFromFrenchTranslationMessages() { Locale.setDefault(Locale.FRANCE); LocalizedException localizedException = new LocalizedException("message.exception"); String franceFrenchLocalizedExceptionMessage = localizedException.getLocalizedMessage(); assertThat(franceFrenchLocalizedExceptionMessage).isEqualTo("Je suis une exception."); } 

5. Предупреждения

5.1. Записване на хвърляния

Ще трябва да имаме предвид логическата рамка, която използваме за изпращане на екземпляри на изключения в дневника.

Log4J, Log4J2 и Logback използват getMessage, за да извлекат съобщението, което да напишат в приложението за регистрация. Ако използваме java.util.logging , съдържанието идва от getLocalizedMessage .

Може да помислим за заместване на getMessage, за да извикаме getLocalizedMessage, така че няма да се притесняваме коя реализация на регистриране се използва.

5.2. Приложения от страна на сървъра

Когато локализираме нашите съобщения за изключения за клиентски приложения, трябва да се притесняваме само за текущия локал на една система . Ако обаче искаме да локализираме съобщения за изключения в сървърно приложение, трябва да имаме предвид, че превключването на подразбиращия се локал ще повлияе на всички заявки в нашия сървър на приложения.

Ако решим да локализираме съобщения за изключения, ще създадем конструктор за нашето изключение, за да приемем Locale . Това ще ни даде възможност да се локализира нашите послания, без да актуализирате по подразбиране на Езикова .

6. Обобщение

Локализирането на съобщенията за изключения е доста лесно. Всичко, което трябва да направим, е да създадем ResourceBundle за нашите съобщения, след което да приложим getLocalizedMessage в нашите подкласове за изключения .

Както обикновено, примерите са достъпни в GitHub.