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 を使用して、クラスパスのルートにあるバンドルにプロパティファイルをロードします。 2つのファイルがあります。1つは英語のメッセージ用で、もう1つはフランス語のメッセージ用です。
# messages.properties
message.exception = I am an exception.
# messages_fr.properties
message.exception = Je suis une exception.
3. ローカライズされた例外クラス
Exception サブクラスは、デフォルトの Locale を使用して、メッセージに使用する翻訳を決定します。 Locale#getDefault を使用して、デフォルトのLocaleを取得します。
アプリケーションがサーバーで実行されている場合、デフォルトを設定する代わりに、HTTPリクエストヘッダーを使用して使用するロケールを識別します。この目的のために、を受け入れるコンストラクターを作成します。ロケール。
Exceptionサブクラスを作成しましょう。 このために、RuntimeExceptionまたはExceptionのいずれかを拡張できます。 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も使用できます。 デフォルトのLocale機能が機能することを確認するために、さらに2つのテストを作成しましょう。
@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. スローアブルのロギング
Exceptionインスタンスをログに送信するために使用しているロギングフレームワークを覚えておく必要があります。
Log4J、Log4J2、およびLogbackは、 getMessage を使用してメッセージを取得し、ログアペンダーに書き込みます。 java.util.logging を使用する場合、コンテンツはgetLocalizedMessageから取得されます。
getMessageをオーバーライドしてgetLocalizedMessageを呼び出すことを検討すると、どのログ実装が使用されているかを気にする必要がなくなります。
5.2. サーバーサイドアプリケーション
クライアントアプリケーションの例外メッセージをローカライズする場合、1つのシステムの現在のLocaleについてのみ心配する必要があります。 ただし、サーバー側アプリケーションで例外メッセージをローカライズする場合は、デフォルトのロケールを切り替えると、アプリケーションサーバー内のすべてのリクエストに影響することに注意してください。
例外メッセージをローカライズすることにした場合は、Localeを受け入れるように例外にコンストラクターを作成します。 これにより、デフォルトのLocaleを更新せずにメッセージをローカライズすることができます。
6. 概要
例外メッセージのローカライズはかなり簡単です。 メッセージ用にResourceBundleを作成し、ExceptionサブクラスにgetLocalizedMessageを実装するだけです。
いつものように、例はGitHubでから入手できます。