Struts2中文字地化問題


一個 Struts2 的國際化定位的問題,用來顯示中國漢字...


案例1:屬性有特殊字元的檔案

屬性檔案儲存使用者名,密碼資訊,並以中文字元提交。此屬性檔案以UTF-8格式建立的,但內容不使用 native2ascii 編碼。

struts2-localization-case1-1

讓我們試著通過一些UI標籤,來顯示中國漢字。檢視頁面宣告為UTF-8格式的HTML元標記來顯示。

...
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
...
<s:form action="validateUser">
	<s:textfield key="global.username" name="username"/>
	<s:password key="global.password" name="password"/>	
	<s:submit key="global.submit" name="submit" />
	
	<div>Testing 1 : <s:property value="getText('global.username')" /></div>
	<div>Testing 2 : <s:text name="global.password" /></div></br/>
</s:form>
...
<s:url id="localezhCN" namespace="/" action="locale" >
   <s:param name="request_locale" >zh_CN</s:param>
</s:url>
...
<s:a href="%{localezhCN}" >Chinese</s:a>
...

結果

令人驚奇的是,以下三個UI標籤都能夠正確地顯示中國訊息
<s:textfield key="global.username" name="username"/>
<s:password key="global.password" name="password"/>	
Testing 2 : <s:text name="global.password" />
然而,「s:submit」 和 「getText()」 卻無法顯示呢?
據Java的國際化文件,要使用資源包正確顯示特殊字元,則必須用 native2ascii 工具進行處理。

深入到 TextProvider.getText()的原始碼後,它使用的資源 bundle.getString()來從資源包檢索的訊息,所以不正確的訊息是合理的。但是,為什麼「s:text「, 「s:textfield」 和 「s:password」 能夠正確顯示了中文的訊息,為什麼「s:submit」會失敗?在有太多的問題,讓我們看看範例2...

案例2:有特殊字元的屬性檔案(編碼)

這一次,屬性檔案使用native2ascii工具處理中國漢字的編碼正確。

struts2-localization-case2-1

結果如下所示:

其結果是完全逆轉,現在 「s:submit」 和 「getText()」 是能夠正確地顯示它,但其他UI元件失敗。 這裡是按預期方式工作的,因為在Struts 2推薦使用getText(),以顯示國際化或在地化的訊息。問題是,為什麼「s:submit」會不同呢?

Struts2..哪裡有問題?

這裡有幾個問題:

  1. 為什麼 s:submit 有如此不同的效果?
  2. 對國際化應該是非常簡單的,為什麼在Struts 2有這種問題? 或者我們誤解了Struts2 國際化如何工作了?
  3. 為什麼有這麼多的方式來顯示來自資源包的訊息?為什麼不直接組織成一個方法? 在Struts1,只需使用「bean:message」,為什麼Struts 2中它看起來很複雜?
  4. Struts2的支援XML資源包? 我們可能不太喜歡用native2ascii工具對資料進行編碼為UTF-8格式,它使屬性檔案不可讀。 Apache Wicket的在這個問題做了很好的工作,可能是在Struts 2中吸取教訓。
  5. 那麼,如何正確地在 Struts2 中顯示中國漢字?
許多文章和教學使用以下方法來顯示資源包的訊息:
<s:text name="global.username"/>
<s:property value="getText('global.username')"/> 

然而,這僅適用於英國或一些「英語狀(歐洲)」 的字元,如法文,德文。但對中文或日文,這兩種方法將返回完全不同的輸出。真的不知道Struts2的在地化該怎麼辦了。

解決辦法

問題是在HTML meta標籤,
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
在Struts1,上述meta標籤必須正確顯示UTF-8的資料,但這在 Struts2 是有問題的。

在Struts2,meta標籤不起作用,我們應該把 <%@ page contentType=」text/html;charset=UTF-8″ %>標籤放在頁面的第一行。例如下面的程式碼片斷:

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
</head>
...

結果顯示如下:

所有的中文訊息正確顯示。

回答之前的問題

  1. 為什麼 s:submit 有如此不同的效果?
    A: 暫無評論
  2. 對國際化應該是非常簡單的,為什麼在Struts 2有這種問題? 或者我們誤解了Struts2 國際化如何工作了?
    A: 
    確保把
     <%@ page contentType=」text/html;charset=UTF-8″ %>」 放在頁面的第一行。
  3. 為什麼有這麼多的方式來顯示來自資源包的訊息?為什麼不直接組織成一個方法? 在Struts1,只需使用「bean:message」,為什麼Struts 2中它看起來很複雜?
    A: s:text, key, getText(), name… , 
    所有的都能夠正確地顯示中文或UTF-8編碼的資料,
    只要確保把正確的「字元集」放在檢視頁面中。
  4. Struts2的支援XML資源包? 我們可能不太喜歡用native2ascii工具對資料進行編碼為UTF-8格式,它使屬性檔案不可讀。 Apache Wicket的在這個問題做了很好的工作,可能是在Struts 2中吸取教訓。
    A:希望在Struts2的下一版本可以支援在XML資源包。
  5. 那麼,如何正確地在 Struts2 中顯示中國漢字?
    A: 看看上頁的解決辦法


參考

  1. /20/206/8011.htmljava-convert-chinese-character-to-unicode-with-native2ascii.html
  2. http://forums.sun.com/thread.jspa?threadID=5185040
  3. http://www.coderanch.com/t/452139/Struts/applicationresources-properties-utf-characters
  4. http://struts.apache.org/2.1.8/docs/localization.html
  5. http://hxzon00.blog.163.com/blog/static/10489241620088121449163/

下載程式碼(globalresource) – http://pan.baidu.com/s/1mgzt3dQ