一、国际化开发概述

(一)、国际化简介

  • 1、软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
  • 2、国际化的概念:一款软件希望不同的国家和地区的使用者都可以使用,这个时候软件中的一些内容和数据需要根据用户地区信息不同而展示成不同的样子。 国际化又称为 i18n:internationalization
  • 3、软件实现国际化,需具备哪些特征:(合格的国际化软件)
  • 对于程序(页面)中固定使用的文本元素,例如菜单栏、导航条等中使用的文本元素、或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不同语言的文本为之服务。
  • 对于程序动态产生的数据,例如(日期,货币等),软件应能根据当前所在的国家或地区的文化习惯进行显示。

(二)、国际化使用

1、国际化第一部分介绍:

  • (1)、页面中固定文本元素的国际化
  • 对于软件中的菜单栏、导航条、错误提示信息,状态信息等这些固定不变的文本信息,可以把它们写在一个properties文件中,并根据不同的国家编写不同的properties文件。这一组properties文件称之为一个资源包
  • 在JavaAPI中提供了一个ResourceBundle 类用于描述一个资源包,并且 ResourceBundle类提供了相应的方法getBundle(),这个方法可以根据来访者的国家地区自动获取与之对应的资源文件予以显示。
  • (2)、创建资源包和资源文件
  • 一个资源包中的每个资源文件都必须拥有共同的basename基名。除了基名,每个资源文件的名称中还必须有标识其本地信息的附加部分。例如:一个资源包的基名是“myproperties”,则与中文、英文环境相对应的资源文件名则为:

“myproperites_zh.properties”
“myproperites_en.properties”

  • 每个资源包都应有一个默认资源文件,这个文件不带有标识本地信息的附加部分。若ResourceBundle对象在资源包中找不到与用户匹配的资源文件,它将选择该资源包中与用户最相近的资源文件,如果再找不到,则使用默认资源文件。例如:

myproperites.properties

  • (3)、语言和国别代码

    java中的国际化 数据库中的数据需要 javaweb国际化_语言环境

  • (4)、资源文件的书写格式
  • 资源文件的内容通常采用“关键字=值”的形式,软件根据关键字检索值显示在页面上。一个资源包中的所有资源文件的关键字必须相同,值则为相应国家的文字。
  • 并且资源文件中采用的是properties格式文件,所以文件中的所有字符都必须是ASCII字码,对于像中文这样的非ACSII字符,须先进行编码。(java提供了一个native2ascII命令用于编码)。例:属性文件是不能保存中文的。(中文属性中输入中文直接转化为unicode编码或者使用JDK中一个命令见下图:命令 回车 输入一个字符 回车 出现unicode编码 或者 其properties窗口添加直接转化)

    java中的国际化 数据库中的数据需要 javaweb国际化_语言环境_02

  • (5)、编程实现固定文本的国际化—-案例:制作国际化登陆页面
  • 1)、加载src下properties文件。

ResourceBundle bundle = ResourceBundle.getBundle(basename);

  • 2)、读取properties文件中内容。

String value = bundle.getString(key);

  • 3)、在读取properties文件时,可以传入一个Locale 实例对象,用于代表一个特定的地理,政治、文化区域。

ResourceBundle bundle =ResourceBundle.getBundle(basename, currentLocale);

  • 如果与该locale对象匹配的资源包子类找不到。一般情况下,则选用操作系统默认资源文件予以显示。


package com.lmd.i18n;import java.util.Locale;import java.util.ResourceBundle;public class ResourceBundleDemo { /* * Locale 对象表示了特定的地理、政治和文化地区。 * ResourceBundle在查找资源文件时,首先找指定的;若未找到,就找操作系统 * 语言环境的;若还找不到,就用默认的 */ public static void main(String[] args) { ResourceBundle bundle1 = ResourceBundle.getBundle("resource"); String name1 = bundle1.getString("username"); System.out.println(name1); //改变系统区域:用户名 or username or default username ResourceBundle bundle2 = ResourceBundle.getBundle("resource",Locale.ENGLISH); String name2 = bundle2.getString("username"); System.out.println(name2); //Locale.ENGLISH:username //Locale.JAPAN:用户名 }}
* IE浏览器--》工具--》Internet选项--》语言--》改变首选语言:

java中的国际化 数据库中的数据需要 javaweb国际化_java中的国际化 数据库中的数据需要_03

java中的国际化 数据库中的数据需要 javaweb国际化_语言环境_04

java中的国际化 数据库中的数据需要 javaweb国际化_java_05

`html

<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> </head> <body> <h4>


Java方式实现的页面国际化

</h4> <%  Locale local = request.getLocale();  ResourceBundle bundle = ResourceBundle.getBundle("resource", local);  %> <form action="#"> <%=bundle.getString("username") %>:<input type="text" /> <%=bundle.getString("password") %>:<input type="password" /> <input type="submit" value="<%=bundle.getString("submit") %>" /> </form> <h4>fmt标签方式实现的页面国际化</h4> <fmt:setBundle basename="resource" var="bundle" scope="page" /> <form action="#"> <fmt:message bundle="${bundle }" key="username"/>:<input type="text" /> <fmt:message bundle="${bundle }" key="password"/>:<input type="password" /> <input type="submit" value="<fmt:message bundle="${bundle }" key="submit"/>" /> </form> </body> </html>

1. 2. ####1.国际化标签:JSTL Java标准标签库
3. * (1).<fmt:setBundle>标签用于根据<fmt:setLocale>标签设置的本地化信息创建一个资源包(ResourceBundle)实例对象,并将其绑定到一个Web域的属性上。<fmt:setBundle>标签的语法格式如下: 
4.  * <fmt:setBundle basename="basename" [var="varName"] [scope="{page|request|session|application}"] />
5.  * 属性名 是否支持EL 属性类型 属 性 描 述
6.  * basename true String 指定创建ResourceBundle实例对象的基名
7.  * var false String 指定将创建出的ResourceBundle实例对象保存到Web域中的属性名称
8.  * scope false String 指定将创建出的ResourceBundle实例对象保存在哪个Web作用域中
9.  <fmt:setBundle>标签有如下一些特性:
10.  * (1)如果basename属性的值为null或空字符串,或找不到basename属性指定的资源,<fmt:setBundle>标签保存到Web域中的属性的值为null。
11.  * (2)如果指定了var属性,<fmt:setBundle>标签将把ResourceBundle实例对象以var属性的值作为域属性名称保存到Web域中;如果没有指定var属性,<fmt:setBundle>标签将把ResourceBundle实例对象以域属性名.
12. * (2).<fmt:message>标签用于从一个资源包中读取信息并进行格式化输出,它有如下一些使用语法格式:
13.  * 语法1,没有标签体的情况:
14.  * <fmt:message key="messageKey" [bundle="resourceBundle"] [var="varName"] [scope="{page|request|session|application}"] />
15. 16.  * 语法2,在标签体中指定格式化文本串中的占位符参数的情况:
17.  * <fmt:message key="messageKey" [bundle="resourceBundle"] [var="varName"][scope="{page|request|session|application}"]>
18.  * <fmt:param>subtags
19.  * </fmt:message>
20. 21.  * 语法3,在标签体中指定消息关键字和可选择的占位符参数:
22.  * <fmt:message [bundle="resourceBundle"] [var="varName"] [scope="{page|request|session|application}"]> key
23.  * optional <fmt:param>subtags
24.  * </fmt:message>
25. 26.  * 属性名 是否支持EL 属性类型 属 性 描 述
27.  * key true String 指定要输出的信息的关键字
28.  * bundle true LocalizationContext 指定ResourceBundle对象在Web域中的属性名称
29.  * var false String 用于指定将格式化结果保存到某个Web域中的某个属性的名称
30.  * scope false String 指定将格式化结果保存到哪个Web域中
31. 32. ###2、国际化第二部分:对程序动态产生的数据的国际化--日期时间/货币/消息
33. ```java
34. java.lang.Object
35.  |---java.text.Format
36.  |---java.text.MessageFormat
37.  |---java.text.NumberFormat
38.  |---java.text.DateFormat
39.  |---java.text.SimpleDateFormat
1–> DateFormat抽象类(国际化日期)—- 日期时间
  • 1.日期时间DateFormat 不能new实例化,但提供的都是static方法

可以将一个日期/时间对象格式化为表示某个国家地区的日期/时间字符串。
DateFormat 类除了可按国家地区格式化输出日期外,它还定义了一些用于描述日期/时间的显示模式的 int 型的常量,包括FULL, LONG, MEDIUM, DEFAULT, SHORT,实例化DateFormat对象时,可以使用这些常量,控制日期/时间的显示长度。
实例化DateFormat类有九种方式。

  • static DateFormat getDateInstance():获取日期格式器,该格式器具有默认语言环境的默认格式化风格。
  • static DateFormat getDateInstance(int style):获取日期格式器,该格式器具有默认语言环境的给定格式化风格。
  • static DateFormat getDateInstance(int style, Locale aLocale):获取日期格式器,该格式器具有给定语言环境的给定格式化风格。
  • static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):获取日期/时间格式器,该格式器具有给定语言环境的给定格式化风格。

  • static DateFormat getTimeInstance():获取时间格式器,该格式器具有默认语言环境的默认格式化风格。
  • static DateFormat getTimeInstance(int style):获取时间格式器,该格式器具有默认语言环境的给定格式化风格。
  • static DateFormat getTimeInstance(int style, Locale aLocale):获取时间格式器,该格式器具有给定语言环境的给定格式化风格。

  • static DateFormat getDateTimeInstance():取日期/时间格式器,该格式器具有默认语言环境的默认格式化风格。
  • static DateFormat getDateTimeInstance(int dateStyle, int timeStyle):获取日期/时间格式器,该格式器具有默认语言环境的给定日期和时间格式化风格。
  • static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):获取日期/时间格式器,该格式器具有给定语言环境的给定格式化风格。

  • String format(Date date)

package com.lmd.dateformat;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;import org.junit.Test;public class DateFormatDemo { /* * 将日期对象转换为字符串表示模式,此时根据地区语言环境不同, * 需要转换为不同样式的字符串 */ public void test1() { Date date = new Date(); DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.CHINESE); String dateStr = format.format(date); System.out.println(dateStr); //2017年3月9日 星期四 上午10时55分44秒 CST DateFormat.FULL Locale.CHINESE //17-3-9 上午10:56 DateFormat.SHORT Locale.CHINESE //2017年3月9日 上午10时57分03秒 DateFormat.LONG Locale.CHINESE //Thursday, March 9, 2017 10:58:30 o'clock AM CST Locale.CANADA //2017年3月9日 10時59分00秒 CST Locale.JAPAN //2017년 3월 9일 목요일 오전 11시 00분 10초 CST Locale.KOREA } /* * 2017年3月9日 星期四 上午10时55分44秒 CST * 将字符串形式的日期时间信息转换为Date对象 */ public void test2() throws ParseException { String dateStr = "2017年3月9日 星期四 上午10时55分44秒 CST"; DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, Locale.CHINA); Date date = format.parse(dateStr); System.out.println(date.toLocaleString()); //2017-3-9 10:55:44 DateFormat.FULL Locale.CHINA }}
  • 2.日期时间 SimpleDateFormat类 (更好些,任意格式对象转换)

是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。

package com.lmd.dateformat;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;import org.junit.Test;public class DateFormatDemo { /* *3月~~9日##2017年**10时%55分%44秒 * 将任意字符串形式的日期时间信息转换为Date对象 */ public void test3() throws ParseException { String dateStr = "03月~~9日##2017年**10时%55分%44秒"; SimpleDateFormat simformat = new SimpleDateFormat("MM月~~dd日##yyyy年**HH时%mm分%ss秒"); Date date = simformat.parse(dateStr); System.out.println(date.toLocaleString()); //2017-3-9 10:55:44 } @Test public void test4() throws ParseException { Date date = new Date(); SimpleDateFormat simformat = new SimpleDateFormat("MM月~~dd日##yyyy年**HH时%mm分%ss秒"); String dateStr = simformat.format(date); System.out.println(dateStr); //03月~~09日##2017年**11时%20分%31秒 }}

####2–> 货币

  • 1.货币–NumberFormat 抽象类

是所有数值格式的抽象基类。此类提供格式化和解析数值的接口。NumberFormat 还提供了一些方法来确定哪些语言环境具有数值格式,以及它们的名称是什么。

  • static NumberFormat getCurrencyInstance():返回当前默认语言环境的货币格式。
  • static NumberFormat getCurrencyInstance(Locale inLocale):返回指定语言环境的货币格式。
  • 1000 – > $1000.00 ¥1000.00

package com.lmd.numberformat;import java.text.NumberFormat;import java.text.ParseException;import java.util.Locale; import org.junit.Test;public class NumberFormatDemo { /* * 将数字表示为字符串,可以根据不同区域语言环境转换为不同的字符串 */ public void test1() { double money = 10000.00; NumberFormat format = NumberFormat.getCurrencyInstance(Locale.UK); String moneyStr = format.format(money); System.out.println(moneyStr); //¥10,000.00 Locale.CHINA  //$10,000.00 Locale.US //£10,000.00 Locale.UK  } /* * $10,000.00 */ @Test public void test2() throws ParseException { String moneyStr = "$10,000.00"; NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US); double money = format.parse(moneyStr).doubleValue(); System.out.println(money); //Locale.CHINA java.text.ParseException: Unparseable number: "$10,000.00" //10000.0 Locale.US }}
3–> 消息国际化
  • 1.消息国际化–MessageFormat

提供了以与语言无关方式生成连接消息的方式。使用此方法构造向终端用户显示的消息。
如果一个字符串中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理

  • 2.例子:At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage
  • 以上字符串中包含了时间、数字、货币等多个与国际化相关的数据,对于这种字符串,可以使用MessageFormat类对其国际化相关的数据进行批量处理。
  • 3.MessageFormat 类如何进行批量处理呢?
  • (1).MessageFormat类允许开发人员用占位符{0}{1}{2}…替换掉字符串中的敏感数据(即国际化相关的数据)。
  • (2).MessageFormat类在格式化输出包含占位符的文本时,messageFormat类可以接收一个参数数组,以替换文本中的每一个占位符。
  • FormatElement:{ ArgumentIndex }、{ ArgumentIndex , FormatType }、 { ArgumentIndex , FormatType , FormatStyle }
  • FormatType: one of number date time choice
  • FormatStyle: short medium long full integer currency percent SubformatPattern

package com.lmd.messageformat;import java.text.MessageFormat;import java.util.Calendar;import java.util.Date;import java.util.Locale;import org.junit.Test;public class MessagFormatDemo { /* * At 12:30 pm on jul 3,1998, a hurricance destroyed 99 * houses and caused $1000000 of damage * 当一个语句中有多个和国际化相关的内容时,需要切割字符串将和国际化相关的数据国际化后再拼接字符串 */ @Test public void test1() { String msgStr = "At {0,time,short} pm on {1,date,long}, a hurricance destroyed" + " {2,number} houses and caused {3,number,currency} of damage"; MessageFormat format = new MessageFormat(msgStr, Locale.CHINA); Calendar c = Calendar.getInstance(); c.set(1998, 6, 3, 12, 30, 00); Date date = c.getTime(); msgStr = format.format(new Object[]{date,date,99,1000000}); System.out.println(msgStr); //At 下午12:30 pm on 1998年7月3日, a hurricance destroyed //99 houses and caused ¥1,000,000.00 of damage }}