(轉)javaweb學習總結(三十一)——國際化(i18n)

  軟件的國際化:軟件開發時,要使它能同時應對世界不一樣地區和國家的訪問,並針對不一樣地區和國家的訪問,提供相應的、符合來訪者閱讀習慣的頁面或數據。
  國際化(internationalization)又稱爲 i18n(讀法爲i 18 n,聽說是由於internationalization(國際化)這個單詞從i到n之間有18個英文字母,i18n的名字由此而來)html

2、合格的國際化軟件

  軟件實現國際化,需具有如下兩個特徵:
  一、對於程序中固定使用的文本元素,例如菜單欄、導航條等中使用的文本元素、或錯誤提示信息,狀態信息等,須要根據來訪者的地區和國家,選擇不一樣語言的文本爲之服務
  二、對於程序動態產生的數據,例如(日期,貨幣等),軟件應能根據當前所在的國家或地區的文化習慣進行顯示java

3、固定文本元素的國際化

  對於軟件中的菜單欄、導航條、錯誤提示信息,狀態信息等這些固定不變的文本信息,能夠把它們寫在一個properties文件中,並根據不一樣的國家編寫不一樣的properties文件。這一組properties文件稱之爲一個資源包編程

3.一、建立資源包和資源文件

  一個資源包中的每一個資源文件都必須擁有共同的基名。除了基名,每一個資源文件的名稱中還必須有標識其本地信息的附加部分。例如:一個資源包的基名是「myproperties」,則與中文、英文環境相對應的資源文件名則爲: "myproperties_zh.properties"  "myproperties_en.properties"數組

  
  每一個資源包都應有一個默認資源文件,這個文件不帶有標識本地信息的附加部分。若ResourceBundle對象在資源包中找不到與用戶匹配的資源文件,它將選擇該資源包中與用戶最相近的資源文件,若是再找不到,則使用默認資源文件。例如:myproperties.properties瀏覽器

3.二、資源文件的書寫格式

  資源文件的內容一般採用"關鍵字=值"的形式,軟件根據關鍵字檢索值顯示在頁面上一個資源包中的全部資源文件的關鍵字必須相同,值則爲相應國家的文字
而且資源文件中採用的是properties格式文件,因此文件中的全部字符都必須是ASCII字碼,屬性(properties)文件是不能保存中文的,對於像中文這樣的非ACSII字符,須先進行編碼。安全

例如:jsp

  國際化的中文環境的properties文件工具

  

  國際化的英文環境的properties文件post

  

  java提供了一個native2ascII工具用於將中文字符進行編碼處理,native2ascII的用法以下所示:測試

  

3.三、編程實現固定文本的國際化

  在JavaAPI中提供了一個ResourceBundle 類用於描述一個資源包,而且 ResourceBundle類提供了相應的方法getBundle,這個方法能夠根據來訪者的國家地區自動獲取與之對應的資源文件予以顯示。

  ResourceBundle類提供了一個靜態方法getBundle,該方法用於裝載資源文件,並建立ResourceBundle實例:

1 Locale currentLocale = Locale.getDefault();
2 ResourceBundle myResources =ResourceBundle.getBundle(basename, currentLocale);

  basename爲資源包基名(且必須爲完整路徑)。
  若是與該locale對象匹配的資源包子類找不到。通常狀況下,則選用默認資源文件予以顯示。 
  加載資源文件後, 程序就能夠調用ResourceBundle 實例對象的 getString 方法獲取指定的資源信息名稱所對應的值。

1  String value =  myResources.getString(「key");

範例:根據國家地區自動獲取與之對應的資源文件

複製代碼
 1 package me.gacl.i18n;
 2 
 3 import java.util.Locale;
 4 import java.util.ResourceBundle;
 5 /**
 6 * @ClassName: I18NTest
 7 * @Description: 編程實現固定文本的國際化
 8 * @author: 孤傲蒼狼
 9 * @date: 2014-8-29 下午9:34:05
10 *
11 */ 
12 public class I18NTest {
13 
14     public static void main(String[] args) {
15         //資源包基名(包名+myproperties)
16         String basename = "me.gacl.i18n.resource.myproperties";
17         //設置語言環境
18         Locale cn = Locale.CHINA;//中文
19         Locale us = Locale.US;//英文
20         //根據基名和語言環境加載對應的語言資源文件
21         ResourceBundle myResourcesCN = ResourceBundle.getBundle(basename,cn);//加載myproperties_zh.properties
22         ResourceBundle myResourcesUS = ResourceBundle.getBundle(basename,us);//加載myproperties_en.properties
23         
24         //加載資源文件後, 程序就能夠調用ResourceBundle實例對象的 getString方法獲取指定的資源信息名稱所對應的值。
25         //String value =  myResources.getString(「key");
26         String usernameCN = myResourcesCN.getString("username");
27         String passwordCN = myResourcesCN.getString("password");
28         
29         String usernameUS = myResourcesUS.getString("username");
30         String passwordUS = myResourcesUS.getString("password");
31         
32         System.out.println(usernameCN+"--"+passwordCN);
33         System.out.println(usernameUS+"--"+passwordUS);
34     }
35 }
複製代碼

  運行結果:

  

3.四、在WEB應用中實現固定文本的國際化

以下所示:

複製代碼
 1 <%@ page language="java"  import="java.util.*" pageEncoding="UTF-8"%>
 2 <!DOCTYPE HTML>
 3 <html>
 4   <head>
 5     <title>國際化(i18n)測試</title>
 6   </head>
 7   <%
 8       //加載i18n資源文件,request.getLocale()獲取訪問用戶所在的國家地區
 9       ResourceBundle myResourcesBundle = ResourceBundle.getBundle("me.gacl.i18n.resource.myproperties",request.getLocale());
10   %>
11   <body>
12         <form action="" method="post">
13             <%=myResourcesBundle.getString("username")%>:<input type="text" name="username"/><br/>
14             <%=myResourcesBundle.getString("password")%>:<input type="password" name="password"/><br/>
15             <input type="submit" value="<%=myResourcesBundle.getString("submit")%>">
16         </form>
17   </body>
18 </html>
複製代碼

運行結果:

  瀏覽器語言是中文環境下的顯示效果:

  

  瀏覽器語言是英文環境下的顯示效果:

  

  一樣一個頁面,在不一樣語言環境的瀏覽器下顯示出了不一樣的語言文字效果,這樣就實現了固定文本的國際化。

  IE瀏覽器切換使用語言:工具→Internet選項

  

  

  

4、動態數據的國際化

  數值,貨幣,時間,日期等數據因爲可能在程序運行時動態產生,因此沒法像文字同樣簡單地將它們從應用程序中分離出來,而是須要特殊處理。Java 中提供瞭解決這些問題的 API 類(位於 java.util 包和 java.text 包中)

4.一、Locale 類

  Locale 實例對象表明一個特定的地理,政治、文化區域。
  一個 Locale 對象自己不會驗證它表明的語言和國家地區信息是否正確,只是向本地敏感的類提供國家地區信息,與國際化相關的格式化和解析任務由本地敏感的類去完成。(若JDK中的某個類在運行時須要根據 Locale 對象來調整其功能,這個類就稱爲本地敏感類)

4.二、DateFormat類(日期格式化)

  DateFormat 類能夠將一個日期/時間對象格式化爲表示某個國家地區的日期/時間字符串。
  DateFormat 類除了可按國家地區格式化輸出日期外,它還定義了一些用於描述日期/時間的顯示模式的 int 型的常量,包括FULL, LONG, MEDIUM, DEFAULT, SHORT,實例化DateFormat對象時,可使用這些常量,控制日期/時間的顯示長度。

4.2.一、實例化DateFormat類

  實例化DateFormat類有九種方式,如下三種爲帶參形式,下面列出的三種方式也能夠分別不帶參,或只帶顯示樣式的參數。
  getDateInstance(int style, Locale aLocale):以指定的日期顯示模式和本地信息來得到DateFormat實例對象,該實例對象不處理時間值部分。
  getTimeInstance(int style, Locale aLocale):以指定的時間顯示模式和本地信息來得到DateFormat實例對象,該實例對象不處理日期值部分。
  getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):以單獨指定的日期顯示模式、時間顯示模式和本地信息來得到DateFormat實例對象。

4.2.二、DateFormat 對象的方法    

  format:將date對象格式化爲符合某個本地環境習慣的字符串。
  parse:將字符串解析爲日期/時間對象
  注意:parse和format徹底相反,一個是把date時間轉化爲相應地區和國家的顯示樣式,一個是把相應地區的時間日期轉化成date對象,該方法在使用時,解析的時間或日期要符合指定的國家、地區格式,不然會拋異常。
  DateFormat 對象一般不是線程安全的,每一個線程都應該建立本身的 DateFormat  實例對象

4.2.三、DateFormat使用範例

複製代碼
 1 package me.gacl.i18n;
 2 
 3 import java.text.DateFormat;
 4 import java.text.ParseException;
 5 import java.util.Date;
 6 import java.util.Locale;
 7 
 8 /**
 9 * @ClassName: DateFormatTest
10 * @Description: DateFormat類測試
11 * DateFormat類能夠將一個日期/時間對象格式化爲表示某個國家地區的日期/時間字符串
12 * @author: 孤傲蒼狼
13 * @date: 2014-8-29 下午10:03:26
14 *
15 */ 
16 public class DateFormatTest {
17 
18     public static void main(String[] args) throws ParseException {
19         Date date = new Date(); // 當前這一刻的時間(日期、時間)
20 
21         // 輸出日期部分
22         DateFormat df = DateFormat.getDateInstance(DateFormat.FULL,Locale.GERMAN);
23         String result = df.format(date);
24         System.out.println(result);
25 
26         // 輸出時間部分
27         df = DateFormat.getTimeInstance(DateFormat.FULL, Locale.CHINA);
28         result = df.format(date);
29         System.out.println(result);
30 
31         // 輸出日期和時間
32         df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG,Locale.CHINA);
33         result = df.format(date);
34         System.out.println(result);
35 
36         // 把字符串反向解析成一個date對象
37         String s = "10-9-26 下午02時49分53秒";
38         df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG,Locale.CHINA);
39         Date d = df.parse(s);
40         System.out.println(d);
41     }
42 }
複製代碼

4.三、NumberFormat類(數字格式化)

  NumberFormat類能夠將一個數值格式化爲符合某個國家地區習慣的數值字符串,也能夠將符合某個國家地區習慣的數值字符串解析爲對應的數值
  NumberFormat類的方法:
    format 方法:將一個數值格式化爲符合某個國家地區習慣的數值字符串
    parse 方法:將符合某個國家地區習慣的數值字符串解析爲對應的數值。
  實例化NumberFormat類時,可使用locale對象做爲參數,也能夠不使用,下面列出的是使用參數的。

  1. getNumberInstance(Locale locale):以參數locale對象所標識的本地信息來得到具備多種用途的NumberFormat實例對象
  2. getIntegerInstance(Locale locale):以參數locale對象所標識的本地信息來得到處理整數的NumberFormat實例對象
  3. getCurrencyInstance(Locale locale):以參數locale對象所標識的本地信息來得到處理貨幣的NumberFormat實例對象
  4. getPercentInstance(Locale locale):以參數locale對象所標識的本地信息來得到處理百分比數值的NumberFormat實例對象

範例:

複製代碼
 1 package me.gacl.i18n;
 2 
 3 import java.text.NumberFormat;
 4 import java.text.ParseException;
 5 import java.util.Locale;
 6 
 7 /**
 8 * @ClassName: NumberFormatTest
 9 * @Description: NumberFormat類測試
10 * @author: 孤傲蒼狼
11 * @date: 2014-8-29 下午10:25:29
12 *
13 */ 
14 public class NumberFormatTest {
15 
16     public static void main(String[] args) throws ParseException {
17         int price = 89;
18 
19         NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CHINA);
20         String result = nf.format(price);
21         System.out.println(result);
22 
23         String s = "¥89.00";
24         nf = NumberFormat.getCurrencyInstance(Locale.CHINA);
25         Number n = nf.parse(s);
26         System.out.println(n.doubleValue() + 1);
27 
28         double num = 0.5;
29         nf = NumberFormat.getPercentInstance();
30         System.out.println(nf.format(num));
31     }
32 }
複製代碼

  運行結果:

  

4.四、MessageFormat(文本格式化)

  若是一個字符串中包含了多個與國際化相關的數據,可使用MessageFormat類對這些數據進行批量處理。
  例如:At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage
  以上字符串中包含了時間、數字、貨幣等多個與國際化相關的數據,對於這種字符串,可使用MessageFormat類對其國際化相關的數據進行批量處理。
  MessageFormat 類如何進行批量處理呢?
    1.MessageFormat類容許開發人員用佔位符替換掉字符串中的敏感數據(即國際化相關的數據)。
    2.MessageFormat類在格式化輸出包含佔位符的文本時,messageFormat類能夠接收一個參數數組,以替換文本中的每個佔位符。

4.4.一、模式字符串與佔位符

模式字符串:

  At {0} on {1},a destroyed {2} houses and caused {3} of damage

  字符串中的{0}、{1}、{2}、{3}就是佔位符

4.4.二、格式化模式字符串

  一、實例化MessageFormat對象,並裝載相應的模式字符串。

  二、使用format(object obj[])格式化輸出模式字符串,參數數組中指定佔位符相應的替換對象。

範例:

複製代碼
 1 package me.gacl.i18n;
 2 
 3 import java.text.MessageFormat;
 4 import java.util.Date;
 5 import java.util.Locale;
 6 
 7 /**
 8 * @ClassName: MessageFormatTest
 9 * @Description: MessageFormat類測試
10 * @author: 孤傲蒼狼
11 * @date: 2014-8-29 下午10:29:19
12 *
13 */ 
14 public class MessageFormatTest {
15 
16     public static void main(String[] args) {
17         //模式字符串
18         String pattern = "On {0}, a hurricance destroyed {1} houses and caused {2} of damage.";
19         //實例化MessageFormat對象,並裝載相應的模式字符串
20         MessageFormat format = new MessageFormat(pattern, Locale.CHINA);
21         Object arr[] = {new Date(), 99, 100000000};
22         //格式化模式字符串,參數數組中指定佔位符相應的替換對象
23         String result = format.format(arr);
24         System.out.println(result);
25     }
26 }
複製代碼

運行結果:

  

4.4.三、佔位符的三種書寫方式

  {argumentIndex}: 0-9 之間的數字,表示要格式化對象數據在參數數組中的索引號
  {argumentIndex,formatType}: 參數的格式化類型
  {argumentIndex,formatType,FormatStyle}: 格式化的樣式,它的值必須是與格式化類型相匹配的合法模式、或表示合法模式的字符串。

範例:

複製代碼
 1 package me.gacl.i18n;
 2 
 3 import java.text.MessageFormat;
 4 import java.util.Date;
 5 import java.util.Locale;
 6 
 7 /**
 8 * @ClassName: MessageFormatTest
 9 * @Description: MessageFormat類測試
10 * @author: 孤傲蒼狼
11 * @date: 2014-8-29 下午10:29:19
12 *
13 */ 
14 public class MessageFormatTest {
15 
16     public static void main(String[] args) {
17         //模式字符串
18         String pattern = "At {0, time, short} on {0, date}, a destroyed {1} houses and caused {2, number, currency} of damage.";
19         //實例化MessageFormat對象,並裝載相應的模式字符串
20         MessageFormat format = new MessageFormat(pattern, Locale.US);
21         Object arr[] = {new Date(), 99, 100000000};
22         //格式化模式字符串,參數數組中指定佔位符相應的替換對象
23         String result = format.format(arr);
24         System.out.println(result);
25     }
26 }
複製代碼

運行結果:

  

5、在WEB應用中使用國際化標籤庫實現固定文本的國際化

複製代碼
 1 <%@ page language="java"  import="java.util.*" pageEncoding="UTF-8"%>
 2 <%--導入國際化標籤庫 --%>
 3 <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
 4 <!DOCTYPE HTML>
 5 <html>
 6   <head>
 7     <title>國際化(i18n)測試</title>
 8   </head>
 9   <%--
10       //加載i18n資源文件,request.getLocale()獲取訪問用戶所在的國家地區
11       ResourceBundle myResourcesBundle = ResourceBundle.getBundle("me.gacl.i18n.resource.myproperties",request.getLocale());
12   --%>
13   <body>
14         <%--
15         <form action="" method="post">
16             <%=myResourcesBundle.getString("username")%>:<input type="text" name="username"/><br/>
17             <%=myResourcesBundle.getString("password")%>:<input type="password" name="password"/><br/>
18             <input type="submit" value="<%=myResourcesBundle.getString("submit")%>">
19         </form>
20         --%>
21         
22     <fmt:setBundle var="bundle"  basename="me.gacl.i18n.resource.myproperties" scope="page"/>
23     <form action="">
24         <fmt:message key="username" bundle="${bundle}"/><input type="text" name="username"><br/>
25         <fmt:message key="password" bundle="${bundle}"/><input type="password" name="password"><br/>
26         <input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>">
27     </form>
28   </body>
29 </html>
複製代碼

   以上就是JavaWeb開發中國際化的總結內容。

相關文章
相關標籤/搜索