1. 程式人生 > >java web--國際化 i18n

java web--國際化 i18n

什麽 date resource format efault 國際化 formate hid 本地

1. 什麽是國際化和本地化:

I. 本地化:一個軟件在某個國家或地區使用時,采用該國家或地區的語言,數字,貨幣,日期等習慣。
II. 國際化:軟件開發時,讓它能支持多個國家和地區的本地化應用。使得應用軟件能夠適應多個地區的語言和文化風俗習慣
III. 本地敏感數據: 隨用戶區域信息而變化的數據稱為本地信息敏感數據。例如數字,貨幣, 日期,時間等數據

2. 相關的 API:

I. DateFormat 和 SimpleDateFormat √.
II. NumberFormat
III. MessageFormat
IV. ResourceBundle
V. Locale

3. 關於國際化資源文件:

I. properties 文件格式
II. 必須提供 基名.properties 文件和 基名_語言代碼_國家代碼.properties 文件
III. 相同的 基名 的資源文件必須有相同的 key.
IV. 可能需要使用 native2ascii 工具把非 asc 碼轉為 asc 碼.

4. WEB 的國際化

I. 可以使用 request.getLocale() 獲取 Locale 對象
II. 可以使用 JSTL 的 fmt 標簽完成的國際化. 後面使用框架提供的標簽完成.
III. 實現 "中文" "英文" 的切換:

> 提供兩個超簡潔. 攜帶不同的變量值
> 根據變量值確定對應的 Locale 對象
> 把 Locale 對象放入到 session 中
> 綁定 Locale 對應的資源文件.

IV. 其他 fmt 標簽可以參考 standard-examples.war 中的例子.

5.代碼區

技術分享圖片

技術分享圖片
package com.atguigu.i18n;

import java.text.DateFormat;
import java.text.MessageFormat; import java.text.NumberFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.ResourceBundle; import org.junit.Test; public class I18nTest { /* @Test public void testMessageFormat2(){ String str = "Date: {0}, Salary: {1}"; Locale locale = Locale.CHINA; Date date = new Date(); double sal = 12345.12; StringBuffer result = new StringBuffer(); FieldPosition fieldPosition = new FieldPosition(0); MessageFormat messageFormat = new MessageFormat(str, locale); messageFormat.format(date, result, fieldPosition); System.out.println(result); } */ /** * ResourceBundle: 資源包類. * * 1. 在類路徑下需要有對應的資源文件: baseName.properties. 其中 baseName 是基名. * 2. 可以使用 基名_語言代碼_國家代碼.properties 來添加不同國家或地區的資源文件. i18n_zh_CN.properties * 3. 要求所有基名相同的資源文件的 key 必須完全一致. * 4. 可以使用 native2ascii 命令來得到 漢字 對一個的 asc 碼. Eclipse 內置了工具 * 5. 可以調用 ResourceBundle 的 getBundle(基名, Locale 實例) 獲取獲取 ResourceBundle 對象 * 6. 可以調用 ResourceBundle 的 getString(key) 來獲取資源文件的 value 字符串的值. * 7. 結合 DateFormat, NumberFormat, MessageFormat 即可實現國際化. * */ @Test public void testResourceBundle(){ Locale locale = Locale.CHINA; ResourceBundle resourceBundle = ResourceBundle.getBundle("i18n", locale); //日期 工資 System.out.println(resourceBundle.getString("date")); System.out.println(resourceBundle.getString("salary")); String dateLabel = resourceBundle.getString("date"); String salLabel = resourceBundle.getString("salary"); String str = "{0}:{1}, {2}:{3}"; Date date = new Date(); double sal = 12345.12; DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale); String dateStr = dateFormat.format(date); NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); String salStr = numberFormat.format(sal); String result = MessageFormat.format(str, dateLabel, dateStr, salLabel, salStr); //日期:2018-1-18, 工資:¥12,345.12 System.out.println(result); } /** * MessageFormat: 可以格式化模式字符串 * 模式字符串: 帶占位符的字符串: "Date: {0}, Salary: {1}" * 可以通過 format 方法會模式字符串進行格式化 */ @Test public void testMessageFormat(){ String str = "Date: {0}, Salary: {1}"; Locale locale = Locale.CHINA; Date date = new Date(); double sal = 12345.12; DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale); String dateStr = dateFormat.format(date); NumberFormat numberFormat = NumberFormat.getCurrencyInstance(locale); String salStr = numberFormat.format(sal); String result = MessageFormat.format(str, dateStr, salStr); //Date: 2018-1-18, Salary: ¥12,345.12 定義信息格式 System.out.println(result); } /** * NumberFormat: 格式化數字到數字字符串, 或貨幣字符串的工具類 * 1. 通過工廠方法獲取 NumberFormat 對象 * NumberFormat.getNumberInstance(locale); //僅格式化為數字的字符串 * NumberFormat.getCurrencyInstance(locale); //格式為貨幣的字符串 * * 2. 通過 format 方法來進行格式化 * 3. 通過 parse 方法把一個字符串解析為一個 Number 類型. */ @Test public void testNumberFormat() throws ParseException{ double d = 123456789.123d; Locale locale = Locale.FRANCE; NumberFormat numberFormat = NumberFormat.getNumberInstance(locale); String str = numberFormat.format(d); //123 456 789,123 System.out.println(str); NumberFormat numberFormat2 = NumberFormat.getCurrencyInstance(locale); str = numberFormat2.format(d); //123 456 789,12 € System.out.println(str); str = "123 456 789,123"; d = (Double) numberFormat.parse(str); //1.23456789123E8 System.out.println(d); str = "123 456 789,12 €"; d = (Double) numberFormat2.parse(str); //1.2345678912E8 System.out.println(d); } @Test public void testDateFormat2() throws ParseException{ String str = "1990-12-12 12:12:12"; DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); //Wed Dec 12 00:12:12 CST 1990 Date date = dateFormat.parse(str); System.out.println(date); } /** * DateFormat: 格式化日期的工具類. * DateFormate 本身是一個抽象類. * * 1. 若只希望通過 DateFormat 把一個 Date 對象轉為一個字符串, 則可以通過 DateFormat 的工廠方法來獲取 DateFormat 對象 * 2. 可以獲取只格式化 Date 的 DateFormat 對象: getDateInstance(int style, Locale aLocale) * 3. 可以獲取只格式化 Time 的 DateFormat 對象: getTimeInstance(int style, Locale aLocale) * 4. 可以獲取既格式化 Date, 也格式化 Time 的 DateFormat 對象: * getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale) * 5. 其中 style 可以取值為: DateFormat 的常量: SHORT, MEDIUM, LONG, FULL. Locale 則為代表國家地區的 Locale 對象 * 6. 通過 DateFormat 的 format 方法來格式化個 Date 對象到字符串. * * 7. 若有一個字符串, 如何解析為一個 Date 對象呢 ? * I. 先創建 DateFormat 對象: 創建 DateFormat 的子類 SimpleDateFormat 對象 * SimpleDateFormat(String pattern). * 其中 pattern 為日期, 時間的格式, 例如: yyyy-MM-dd hh:mm:ss * II. 調用 DateFormat 的 parse 方法來解析字符串到 Date 對象. * */ @Test public void testDateFormat(){ Locale locale = Locale.CHINA; Date date = new Date(); //Thu Jan 18 14:29:48 CST 2018 System.out.println(date); //獲取 DateFormat 對象 2018年1月18日 14:30:29 DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM, locale); String str = dateFormat.format(date); System.out.println(str); } /** * Locale: Java 中表示國家或地區的類. JDK 中提供了很多常量. * 也可以通過 Locale(languageCode, countryCode) 的方式來創建 * 在 WEB 應用中可以通過 request.getLocale() 方法來獲取. */ @Test public void testLocale(){ Locale locale = Locale.CHINA; // 中國 zh System.out.println(locale.getDisplayCountry()); System.out.println(locale.getLanguage()); // 美國 en locale = new Locale("en", "US"); System.out.println(locale.getDisplayCountry()); System.out.println(locale.getLanguage()); } }
I18nTest 技術分享圖片
date=Date
salary=Salary
i18n_en_US.properties 技術分享圖片
date=\u65E5\u671F
salary=\u5DE5\u8D44
i18n_zh_CN.properties 技術分享圖片
date=Date
salary=Salary
i18n.properties 技術分享圖片
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>i18n</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>
web.xml 技術分享圖片
<%@page import="java.util.Locale"%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
     
    <% 
        Date date = new Date();
        request.setAttribute("date", date);
        request.setAttribute("salary", 12345.67);
    %>
    
    <%-- 
    <fmt:bundle basename="i18n">
        <fmt:message key="date"></fmt:message>: 
        <fmt:formatDate value="${date }"/>,
        <fmt:message key="salary"></fmt:message>:
        <fmt:formatNumber value="${salary }"></fmt:formatNumber>
    </fmt:bundle>
    <br><br>
    --%>
    
    <% 
        String code = request.getParameter("code");
    
        if(code != null){
            if("en".equals(code)){
                session.setAttribute("locale", Locale.US);
            }else if("zh".equals(code)){
                session.setAttribute("locale", Locale.CHINA);
            }
            
        }
    %>
    
    <c:if test="${sessionScope.locale != null }">
        <fmt:setLocale value="${sessionScope.locale }"/>
    </c:if>
    
    <fmt:setBundle basename="i18n"/>
    
    <fmt:message key="date"></fmt:message>: 
    <fmt:formatDate value="${date }" dateStyle="FULL"/>,
    <fmt:message key="salary"></fmt:message>:
    <fmt:formatNumber value="${salary }" type="currency"></fmt:formatNumber>
    <br><br>
    
    <a href="index.jsp?code=en">English</a>
    <a href="index.jsp?code=zh">中文</a>
    
</body>
</html>
index.jsp

技術分享圖片

技術分享圖片

java web--國際化 i18n