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
0 评论