前幾天圍繞着JDBC程式設計進行了系統的學習。現在我們對Java程式資料庫操作已經是輕車熟路了。也學會了使用各種架構來幫助我們簡化程式設計。
今天是學習計劃的第七天,雖然學習熱情沒有前幾天高漲了。但是,寫部落格總結的習慣應該要堅持下去。廢話不多說了。
今天的學習内容是JavaWeb開發——軟體國際化。
軟體的國際化:軟體開發時,要使它能同時應對世界不同地區和國家的通路,并針對不同地區和國家的通路,提供相應的、符合來訪者閱讀習慣的頁面或資料。
國際化又稱為 i18n:internationalization。
通俗一點就是說,一套軟體提供多套不同的界面,根據來訪者的國家和語言的不同,進而顯示對應的界面。
其實JDK就實作了軟體國際化,在dos視窗輸入javac指令,dos視窗就會彈出中文資訊。而當你改變你電腦的語言為英文,再次到dos視窗輸入javac指令,dos視窗彈出的就是英文資訊了。
軟體實作國際化,需具備哪些特征:
- 對于程式中固定使用的文本元素,例如菜單欄、導覽列等中使用的文本元素、或錯誤提示資訊,狀态資訊等,需要根據來訪者的地區和國家,選擇不同語言的文本為之服務。
- 對于程式動态産生的資料,例如(日期,貨币等),軟體應能根據目前所在的國家或地區的文化習慣進行顯示。
我們先看第一個特征
固定文本元素的國際化
- 對于軟體中的菜單欄、導覽列、錯誤提示資訊,狀态資訊等這些固定不變的文本資訊,可以把它們寫在一個properties檔案中,并根據不同的國家編寫不同的properties檔案。這一組properties檔案稱之為一個資源包。
- 在JavaAPI中提供了一個ResourceBundle 類用于描述一個資源包,并且 ResourceBundle類提供了相應的方法getBundle,這個方法可以根據來訪者的國家地區自動擷取與之對應的資源檔案予以顯示。
建立資源包和資源檔案的一些注意事項
- 一個資源包中的每個資源檔案都必須擁有共同的基名。除了基名,每個資源檔案的名稱中還必須有辨別其本地資訊的附加部分。例如:一個資源包的基名是“myproperties”,則與中文、英文環境相對應的資源檔案名則為:“myproperites_zh.properties” “myproperites_en.properties”。
- 每個資源包都應有一個預設資源檔案,這個檔案不帶有辨別本地資訊的附加部分。若ResourceBundle對象在資源包中找不到與使用者比對的資源檔案,它将選擇該資源包中與使用者最相近的資源檔案,如果再找不到,則使用預設資源檔案。例如myproperites.properties。
貼上一張語言和國家代碼
語言代碼 | 說明 | | | 國家代碼 | 說明 |
---|---|---|---|---|
De | German | | | CN | China |
es | Spanish | | | CA | Canada |
En | English | 分 | DE | Germany |
Fr | French | 割 | FR | France |
Ja | Japanese | 線 | IN | India |
Jw | Javanese | | | US | United State |
ko | Korean | | | ||
Zh | Chinese | | |
有了這張表以後,就可以通過對照該表來編寫适合各個國家語言的資源檔案。 資源檔案的命名規則為:基名_語言_國家.properties,這裡的國家是可以省略的。 例如:myproperties_zh_CN.properties 代表中國,一般國家代碼大寫,語言代碼小寫。 myproperties_en_US.properties 代表美國 。
資源包的檔案一般建立在src目錄下。
示範一下。
建立web項目,名為day07。
在src目錄下建立三個配置檔案,分别為myproperties.properties、myproperties_zh_CN.properties、myproperties_en_US.properties。
在myproperties.properties檔案下編寫
name = default
在myproperties_zh_CN.properties檔案下編寫
name = 張三
在myproperties_en_US.properties檔案下編寫
name = mary
有些同學會發現編寫 name = 張三 的配置檔案無法儲存,因為配置檔案是不能儲存中文的。順便科普一下資源檔案的書寫格式。
- 資源檔案的内容通常采用“關鍵字=值”的形式,軟體根據關鍵字檢索值顯示在頁面上。一個資源包中的所有資源檔案的關鍵字必須相同,值則為相應國家的文字。
- 并且資源檔案中采用的是properties格式檔案,是以檔案中的所有字元都必須是ASCII字碼,對于像中文這樣的非ACSII字元,須先進行編碼。(java提供了一個native2ascII指令用于編碼)。
是以如果想在配置檔案中儲存中文,就得先把中文轉成Unicode,那如何轉換呢?
我們可以先打開一個dos視窗,然後在視窗中輸入
native2ascii
,回車後dos視窗會等待使用者輸入,此時你可以輸入要轉換的中文資訊,比如輸入張三,視窗就會顯示出對應的Unicode編碼。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICMyYTMvw1dvwlMvwlM3VWaWV2Zh1Wa-cmbw5iehVWetVWazI2Zvw1N4YjN1YzMtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.png)
現在将幾個中文漢字進行Unicode編碼我們已經能夠實作了,但是如果有大量的中文資料需要批量轉換應該怎麼辦呢?
在桌面上建立一個a.properties檔案,然後輸入
name = 張三
city = 北京
我們的目的是将該檔案的所有内容轉成Unicode編碼。
打開dos視窗,将路徑切換到你的檔案目錄,也就是切換到桌面目錄,然後輸入
native2ascii a.properties b.properties
複制
第一個檔案為要轉碼的檔案,第二個檔案為生成的Unicode編碼檔案。
回到桌面,發現多了一個b.properties檔案,打開一看,兩個中文資訊已經被轉換成了Unicode編碼了。
用這個小工具就能夠輕松實作中文轉Unicode編碼問題。
好像有點偏離主題了。哈哈,請原諒我這顆愛分享的心。
咳咳,繼續今天的内容哈。
有了配置檔案之後,我們就應該讀取檔案了。
建立測試類,編寫測試代碼
@Test
public void demo1(){
//使用ResourceBundle讀取配置檔案,不設定國家
ResourceBundle bundle = ResourceBundle.getBundle("myproperties");
//預設根據系統語言選擇配置檔案
System.out.println(bundle.getString("name"));
}
複制
運作代碼
說明運作的是中文資訊的配置檔案。
在Java中存在這樣一個類,Locale類,它代表了國家和語言。它有什麼作用呢?
通過案例感受一下。
編寫測試代碼
@Test
public void demo2(){
//讀取檔案時,設定國家
Locale locale = new Locale("en","US");//指定國家為美國
ResourceBundle bundle = ResourceBundle.getBundle("myproperties",locale);
System.out.println(bundle.getString("name"));
}
複制
運作代碼
說明運作的是英文資訊的配置檔案。Locale類的作用應該一目了然吧。
這裡有一個優先級的問題,就是設定Locale類的優先級是最高的,你設定的是哪個國家和語言,運作的就是哪個語言的配置檔案,其次是系統國家設定,最後是預設的。
基礎知識就介紹完畢了,接下來我們來編寫一個登入案例加深一下了解。
建立login.jsp檔案
<%@page import="java.util.ResourceBundle"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%
ResourceBundle bundle = ResourceBundle.getBundle("myproperties");
%>
<h1><%=bundle.getString("forminfo") %></h1>
<form>
<%=bundle.getString("username") %><input type="text" name="username" /><br />
<%=bundle.getString("password") %><input type="password" name="password" /><br />
<input type="submit" value="<%=bundle.getString("submit") %>" />
</form>
</body>
</html>
複制
現在,對jsp的文本元素進行國際化。
分别修改配置檔案,首先修改myproperties.properties檔案
forminfo = default Login Form
username = default Username
password = default Password
submit = default Submit
複制
然後修改myproperties_en_US.properties檔案
forminfo = Login Form
username = Username
password = Password
submit = Submit
複制
最後修改myproperties_zh_CN.properties檔案
forminfo = \u767B\u5F55\u8868\u5355
username = \u7528\u6237\u540D
password = \u5BC6\u7801
submit = \u63D0\u4EA4
複制
将項目部署運作
因為我們沒有指定國家,是以應該以系統預設為準,顯示的是中文資訊。
現在我們手動指定一下國家。
将login.jsp檔案修改一下
ResourceBundle bundle = ResourceBundle.getBundle("myproperties",Locale.US);
複制
隻需要将建立ResourceBundle對象的代碼作如上修改即可,在Locale類中定義了各種與國家對應的常量,是以我們直接可以在建構ResourceBundle對象時将Locale類的字段傳入即可。
現在重新運作一下程式。
上面已經說過了,Locale類設定的國家優先級是最高的,是以顯示了英文資訊。
上面的代碼大量使用使用了<%=%>,不僅麻煩,而且不美觀,我們可以使用JSTL去顯示資料。
修改login.jsp檔案
<%@page import="java.util.Locale"%>
<%@page import="java.util.ResourceBundle"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--引入國際化标簽庫--%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%
ResourceBundle bundle = ResourceBundle.getBundle("myproperties",Locale.US);
%>
<h1><%=bundle.getString("forminfo") %></h1>
<form>
<%=bundle.getString("username") %><input type="text" name="username" /><br />
<%=bundle.getString("password") %><input type="password" name="password" /><br />
<input type="submit" value="<%=bundle.getString("submit") %>" />
</form>
<hr/>
<fmt:setLocale value="zh_CN"/>
<fmt:setBundle basename="myproperties" var="bundle" scope="page"/>
<h1><fmt:message key="forminfo" bundle="${bundle }"/></h1>
<form>
<fmt:message key="username" bundle="${bundle }"/><input type="text" name="username" /><br />
<fmt:message key="password" bundle="${bundle }"/><input type="password" name="password" /><br />
<input type="submit" value="<fmt:message key="submit" bundle="${bundle }"/>" />
</form>
</body>
</html>
複制
運作項目
同樣成功實作了效果,但是代碼看起來就會比第一種實作方式簡潔、舒服。
因為篇幅有限,軟體國際化的内容在一篇部落格中講完是不太現實的,這一部分的内容我就大概分三個部分去講解,是以這是一個系列,就分為
- 文本元素國際化
- 動态資料國際化
- 動态文本國際化
這三個部分吧。大家閱讀的時候可以按從上往下的順序閱讀。