Struts Message Resources

Struts Message Resources

作者:Nick Heudecker    來自:未知

總覽

許多剛剛學習Struts的程序員在使用Struts的MessageResources特性的時候會遭遇很多困難。本文將試圖闡述MessageResources特性的優點並給出了具體的例子說明它的用法。

作者: Nick Heudecker, System Mobile Inc.

概述

類MessageResources可以使開發者方便地支持多語言,包括支持多時間格式和數字格式。使用資源包的另一個好處是允許開發者將標籤字符串集中存儲在一個位置,而不是分散在不同的JSP頁面裏。例如,對於每個用戶的名字的標籤"First Name" ,我們可以將它寫在資源包中,在適當的地方通過Struts標籤簡單的進行引用:

<bean:write key="label.first.name"/>

這樣做將會讓你對程序的更改變的簡單容易,你不必在每一個JSP頁面裏更改標籤的內容了。

用法

使用消息資源包需要你做下面的事情:

1. 爲你想要支持的地方創建一個消息資源包。
2. 配置WEB應用,加載消息資源包。
3. 使用相應的JSP標籤加載資源或者...
4. ...在一個Action類中加載資源。

創建資源包

MessageResources 類的默認的實現是一個包含"key=value" 對的文件,下面的一個消息資源包文件的例子。

label.username=Username
label.password=Password
label.first.name=First Name
label.last.name=Last Name
label.email=Email Address
label.phone.number=Phone Number
label.welcome=Welcome back {0} {1}!
error.min.length=The input must be at least {0} characters in length.
error.max.length=The input cannot be longer than {0} characters in length.

大括號包圍的整數是對java.text.MessageFormat 類的支持,程序員可以向value字符串中傳遞參數,對每個value字符串你最多可以傳遞4個參數。

配置

有兩種途徑通知Struts你的資源包的位置:web.xml 文件或者struts-config.xml 文件。首先來看web.xml 文件的配置:

<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
    org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>
    application
</param-name>
<param-value>
    com.systemmobile.example.ApplicationResources
</param-value>
</init-param>
</servlet>

這個配置說明你的資源包的名字是ApplicationResources.properties,它位於com.systemmobile.example 包中。後綴".properties" 是隱含的,你不必顯式地寫出來。如果你還有另一個資源文件在相同的包中,例如ApplicationResources_fr.properties ,用來支持法語,你只需要象上面定義的那樣列出文件名字即可。

定義資源文件的第二中方法(上面已經提到),是在struts-config.xml 文件中配置:

<message-resources parameter="com.systemmobile.example.ApplicationResources"/>

屬性parameter 是必須的。和在web.xml文件中配置一樣, 需要注意的是文件在包中的位置。

使用struts-config.xml 文件來配置消息資源文件是推薦的做法,因爲它更有可擴展性,更靈活。

  • 你可以使用message-resources 標籤從不同的資源文件取不同的消息,前提是在配置的時候爲不同的資源文件給出不同的key 屬性的值。例如:
    <message-resources key="myResources" parameter="com.systemmobile.example.
    ApplicationResources"/> <message-resources key="moreResources" parameter="com.systemmobile.example.
    MoreApplicationResources"/>
    然後你必須這樣使用bean:message 標籤:
    <bean:message bundle="moreResources" key="some.message.key"/>
  • 設置屬性null 的值爲"false" 後,如果某個資源字符串不存在將返回???key??? 而不是僅僅顯示null。這樣很容易在JSP頁面中看到你沒有定義的資源,使得內部測試的速度更快。(關於如何從資源文件中獲得消息的詳細內容參見國際化 一節)
    <message-resources parameter="com.systemmobile.example.ApplicationResources" null="false"/>
  • 另外,message-resources 標籤允許你使用自己實現的MessageResourcesFactory 接口,這不在本文的討論範圍。

資源文件放在哪裏

關於資源文件最常見的問題是將資源文件放在WAR文件的哪裏。簡單的回答是該文件必須放在你的classpath下面,這意味着將資源文件放在一個JAR 文件中,或者放在/WEB-INF/classes 目錄極其子目錄下。下表給出了資源文件的位置,在message-resources 標籤中"parameter" 屬性的值以及簡短的說明。

Resources Locationparameter ValueDescription
/WEB-INF/classes/ApplicationResources.propertiesApplicationResources文件放在classes 目錄下, 該目錄在web應用的classpath中.
/WEB-INF/classes/resources/ApplicationResources.propertiesresources.ApplicationResources該文件放在"resources" 目錄下, 所以包名也就是路徑名要給出。
In the app.jar file, in the com.systemmobile.example package/directory.com.systemmobile.example.ApplicationResources文件在JAR文件中的全路徑。

Tags

最常用Struts 標籤是bean:message 標籤。使用這個標籤的"key" 可以從資源文件中讀特定的消息資源。你還可以傳入四個參數中的一個或全部:

<bean:message key="label.password"/>
<bean:message key="error.min.length" arg0="6"/>
<bean:message key="label.welcome" arg0="Ralph" arg1="Nader"/>

html:message 可以讓你向用戶顯示錯誤信息(默認)或消息信息,而html:errors 只顯示錯誤信息。很明顯,錯誤信息或消息信息一定要保存在request裏,否則就什麼也不會顯示。這裏有一個顯示消息信息的例子:

<logic:messagesPresent message="true">
  <html:messages id="msg" message="true">
    <div class="success">
      <bean:write name="msg"/>
    </div><br/>
  </html:messages>
</logic:messagesPresent>

還有一些標籤也有限地支持消息資源,比如html:link。html:link標籤通過定義"titleKey" 屬性來顯示標題文本。許多html 使用 "altKey" 屬性從資源文件裏獲得alternate(替代)文本。

Actions

你還可以在Action 類中使用消息資源文件。Action 類有兩個方法得到一個MessageResource 類的實例:

// 返回一個request裏的資源文件
protected MessageResources getResources(HttpServletRequest request);
// 返回一個request裏的資源文件,
// 該資源文件的標誌上<message-resources/> 元素的內容
protected MessageResources getResources(javax.servlet.http.HttpServletRequest request,
java.lang.String key);

MessageResources類可以讓你從資源文件中得到本地化的消息。The API for MessageResources 可以在資源中找到。比較常用的方法有:

// these methods load a resources key for the given locale
public String getMessage(java.util.Locale locale, java.lang.String key);
public String getMessage(java.util.Locale locale, java.lang.String key, 
       java.lang.Object arg0);
public String getMessage(java.util.Locale locale, java.lang.String key, 
       java.lang.Object[] args);
public String getMessage(java.util.Locale locale, java.lang.String key, 
       java.lang.Object arg0, java.lang.Object arg1)
public String getMessage(java.util.Locale locale, java.lang.String key, 
       java.lang.Object arg0, java.lang.Object arg1, java.lang.Object arg2);
public String getMessage(java.util.Locale locale, java.lang.String key, java.lang.Object arg0,
       java.lang.Object arg1, java.lang.Object arg2, java.lang.Object arg3);
// these methods load a resources key for the locale retrieved
// from the HttpServletRequest
public String getMessage(java.lang.String key);
public String getMessage(java.lang.String key, java.lang.Object arg0);
public String getMessage(java.lang.String key, java.lang.Object[] args);
public String getMessage(java.lang.String key, java.lang.Object arg0, 
       java.lang.Object arg1);
public String getMessage(java.lang.String key, java.lang.Object arg0, 
       java.lang.Object arg1, java.lang.Object arg2);
public String getMessage(java.lang.String key, java.lang.Object arg0, 
       java.lang.Object arg1, java.lang.Object arg2, java.lang.Object arg3);

這些返回的字符串可以被設置成request 或 session 的參數並串會表現層。你可能注意到了一些重載方法getMessage(...) 選擇了參數Object,而另外一些採用了參數arg0...arg3。這和 bean:message arg0...arg3 屬性等價。

除了MessageResources 類,還有一些類使用了資源文件。ActionMessage類被用來從action 向JSP之間傳遞消息資源中的keys 。消息被用來作爲bean 的屬性。ActionError, ActionMessage的子類,使用消息資源中的keys 存儲驗證失敗後的錯誤信息。

國際化

從資源文件中提取一個本地化信息可以由類MessageResources 來處理,或者由它的直接子類PropertyMessageResources類處理。既然類PropertyMessageResources 等經常地被用到,那麼我們就來看看它是怎樣使用getMessage(Locale, String) 方法來從資源文件中讀取消息的。

舉例說明:

1. 如果你在ApplicationResources_pt_br.properties (Brazilian Portuguese)中沒有發現消息的定義,系統將在ApplicationResources_pt.properties 文件中找,如果ApplicationResources_pt.properties 文件不存在或者也沒有該消息,那就去ApplicationResources.properties 文件裏查找了。
2. 如果消息找到了,它就被加到本地化的緩存中並返回java.lang.String型數據。
3. 如果消息沒有找到,此時如果returnNull 屬性被爲默認的true,將返回 null。 否則將返回類似 ???key??? 的字符串,key 就是那個被傳遞的參數。

JSTL

JSTL (JavaServer Pages Standard Tag Library) 的fmt標籤最近開始流行起來,用來向JSP中顯示資源文件的信息。它能很好地和Struts結合在一起。使用它非常簡單,只要下載JSTL 的jar 文件和TLDs 並把它們拷貝到你的應用的正確的位置,然後在web.xml文件中加入下面的內容:

<context-param>
  <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
  <param-value>ApplicationResources</param-value>
</context-param>

上面的配置是假定你的ApplicationResources.properties文件是放在/WEB-INF/classes 目錄下的。 參見above 更多情況。

然後將這個標籤庫直接放在你的JSP中:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>

最後,下面的標籤將顯示資源文件的內容:

<fmt:message key="label.first.name"/>

還有一個使用fmt 標籤獲得資源的例子。(注意: 該段程序取自Jakarta JSTL examples。)

// loading a resource from a specific bundle and populating a parameter
<fmt:message key="currentTime" bundle="${deBundle}">
 <fmt:param value="${currentDateString}"/>
</fmt:message>
// using the forEach iterator to populate paramters
<fmt:message key="serverInfo" bundle="${deBundle}">
 <c:forEach var="arg" items="${serverInfoArgs}">
  <fmt:param value="${arg}"/>
 </c:forEach>
</fmt:message>

結論

在向JSP文件方便地傳遞消息的同時,Struts使用消息資源文件還幫助我們創建國際化的Web應用。我們既可以使用正在快速發展中的JSTL標籤,也可以使用Struts標籤,或直接在action中得到一條具體的消息。我希望這篇文章爲您闡明瞭一些Struts中常用的但有時會混淆的東西。

關於作者

Nick Heudecker 是一位軟件開發人員,具有6年的企業應用的開發經驗。 他所在的公司, System Mobile, Inc.,專門從事應用集成,定製軟件開發和無線應用。 他還是Sun認證JAVA程序員,現在居住在Ann Arbor, Michigan。

資源

下面的資源也許對您瞭解更多的關於Struts資源文件有幫助:

注意事項

Packages are just directory structures used to avoid naming conflicts. If you put a message bundle in a directory named resources under /WEB-INF/classes, this is the equivalent of putting the file in a package named resrouces. While basic, this point seems to trip up many new programmers.
發佈了56 篇原創文章 · 獲贊 0 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章