3.8.1. 利用MessageSource
實現國際化
ApplicationContext
接口擴展了MessageSource
接口,因而提供了消息處理的功能(i18n或者國際化)。與HierarchicalMessageSource
一起使用,它還能夠處理嵌套的消息,這些是Spring提供的處理消息的基本接口。讓我們快速瀏覽一下它所定義的方法:
-
String getMessage(String code, Object[] args, String default, Locale loc):用來從MessageSource
獲取消息的基本方法。如果在指定的locale中沒有找到消息,則使用默認的消息。args中的參數將使用標準類庫中的MessageFormat
來作消息中替換值。
-
String getMessage(String code, Object[] args, Locale loc):本質上和上一個方法相同,其區別在:沒有指定默認值,如果沒找到消息,會拋出一個NoSuchMessageException
異常。
-
String getMessage(MessageSourceResolvable resolvable, Locale locale)
:上面方法中所使用的屬性都封裝到一個MessageSourceResolvable
實現中,而本方法可以指定MessageSourceResolvable
實現。
當一個ApplicationContext
被加載時,它會自動在context中查找已定義為MessageSource
類型的bean。此bean的名稱須為messageSource
。如果找到,那么所有對上述方法的調用將被委托給該bean。否則ApplicationContext
會在其父類中查找是否含有同名的bean。如果有,就把它作為MessageSource
。如果它最終沒有找到任何的消息源,一個空的StaticMessageSource
將會被實例化,使它能夠接受上述方法的調用。
Spring目前提供了兩個MessageSource
的實現:ResourceBundleMessageSource
和StaticMessageSource
。它們都繼承NestingMessageSource
以便能夠處理嵌套的消息。StaticMessageSource
很少被使用,但能以編程的方式向消息源添加消息。ResourceBundleMessageSource
會用得更多一些,為此提供了一下示例:
<beans>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
<value>windows</value>
</list>
</property>
</bean>
</beans>
這段配置假定在你的classpath中有三個資源文件(resource bundle),它們是format
, exceptions
和windows
。通過ResourceBundle,使用JDK中解析消息的標準方式,來處理任何解析消息的請求。出于示例的目的,假定上面的兩個資源文件的內容為…
# in 'format.properties'
message=Alligators rock!
# in 'exceptions.properties'
argument.required=The '{0}' argument is required.
下面是測試代碼。因為ApplicationContext
實現也都實現了MessageSource
接口,所以能被轉型為MessageSource
接口
public static void main(String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("message", null, "Default", null);
System.out.println(message);
}
上述程序的輸出結果將會是...
Alligators rock!
總而言之,我們在'beans.xml'
的文件中(在classpath根目錄下)定義了一個messageSource
bean,通過它的basenames
屬性引用多個資源文件;而basenames
屬性值由list元素所指定的三個值傳入,它們以文件的形式存在并被放置在classpath的根目錄下(分別為format.properties
,exceptions.properties
和windows.properties
)。
再分析個例子,這次我們將著眼于傳遞參數給查找的消息,這些參數將被轉換為字符串并插入到已查找到的消息中的占位符(譯注:資源文件中花括號里的數字即為占位符)。
<beans>
<!-- this MessageSource
is being used in a web application -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="baseName" value="WEB-INF/test-messages"/>
</bean>
<!-- let's inject the above MessageSource
into this POJO -->
<bean id="example" class="com.foo.Example">
<property name="messages" ref="messageSource"/>
</bean>
</beans>
public class Example {
private MessageSource messages;
public void setMessages(MessageSource messages) {
this.messages = messages;
}
public void execute() {
String message = this.messages.getMessage("argument.required",
new Object [] {"userDao"}, "Required", null);
System.out.println(message);
}
}
調用execute()
方法的輸出結果是...
The 'userDao' argument is required.
對于國際化(i18n),Spring中不同的MessageResource
實現與JDK標準ResourceBundle中的locale解析規則一樣。比如在上面例子中定義的messageSource
bean,如果你想解析British (en-GB) locale的消息,那么需要創建format_en_GB.properties
,exceptions_en_GB.properties
和windows_en_GB.properties
三個資源文件。
Locale解析通常由應用程序根據運行環境來指定。出于示例的目的,我們對將要處理的(British)消息手工指定locale參數值。
# in 'exceptions_en_GB.properties'
argument.required=Ebagum lad, the '{0}' argument is required, I say, required.
public static void main(final String[] args) {
MessageSource resources = new ClassPathXmlApplicationContext("beans.xml");
String message = resources.getMessage("argument.required",
new Object [] {"userDao"}, "Required", Locale.UK);
System.out.println(message);
}
上述程序運行時的輸出結果是...
Ebagum lad, the 'userDao' argument is required, I say, required.
MessageSourceAware
接口還能用于獲取任何已定義的MessageSource
引用。任何實現了MessageSourceAware
接口的bean將在創建和配置的時候與MessageSource
一同被注入。
posted on 2008-11-22 16:51
xzc 閱讀(4099)
評論(3) 編輯 收藏 所屬分類:
Java