在Java中本地化異常消息
- java
- Exception
1.概述
Java中的異常用於表示程序中出現了問題。除了引發異常外,我們甚至可以添加一條消息以提供其他信息。
在本文中,我們將利用getLocalizedMessage方法來提供英語和法語的異常消息。
2.資源包Resource Bundle
我們需要一種使用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.本地化的異常類
我們的Exception子類將使用默認的Locale來確定要為我們的消息使用的翻譯。我們將使用Locale#getDefault獲得默認的Locale 。
如果我們的應用程序在服務器上運行,我們將使用HTTP請求標頭來標識Locale ,而不是設置默認語言環境。為此,我們將創建一個構造函數以接受Locale.
讓我們創建我們的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功能是否正常工作:
@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 服務器端應用程序
當我們為客戶端應用程序本地化異常消息時,我們只需要擔心一個系統的當前Locale 。但是,如果要在服務器端應用程序中本地化異常消息,則應記住,切換默認Locale將影響應用程序服務器內的所有請求。
如果我們決定本地化異常消息,我們將在異常上創建一個構造函數以接受Locale 。這將使我們能夠在不更新默認Locale的情況下本地化消息。
6.總結
本地化異常消息非常簡單。我們需要做的就是為我們的消息ResourceBundle ,然後在我們的Exception子類中getLocalizedMessage