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