一、概述

  • 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
  • 国际化开发的(JavaWeb)具体:如 根据不同国家的来访者提供不同的语言
  • 国际化又简称为 i18n:internationalization
  • 区别翻译软件

1.1、合格的国际化软件

合格的国际化软件必须包含静态数据和动态数据的国际化。

 

1.2、固定文本元素的国际化

  • 软件中固定不变的信息(菜单栏、导航条、错误提示信息等)写在一个properties文件中,根据不同的国家编写不同properties文件。这一组properties文件称之为一个资源包
  • JavaAPI提供了一个ResourceBundle 类用于描述一个资源包,该类提供了一个getBundle方法可以根据来访者的国家地区自动获取相应的资源文件予以显示。

1.3、创建资源包与资源文件

  • 资源包与资源文件必须由共同的基名
  • 每个资源文件的名称中还必须有标识其本地信息的附加部分
  • 举例:一个资源包的基名是“properties”,则与中文、英文环境相对应的资源文件名则为: “properites_zh.properties”  “properites_en.properties”
  • 每个资源包都应有一个默认资源文件,这个文件不带有标识本地信息的附加部分若ResourceBundle对象在资源包中找不到与用户匹配的资源文件,它将选择该资源包中与用户最相近的资源文件,如果再找不到,则使用默认资源文件;举例“properties.proerties”

java国际语言 java国际化重要吗_字符串

 

 

1.4、资源文件的书写格式

  • 资源文件中采用的是properties格式文件,所以文件中的所有字符都必须是ASCII字码。
  • 像中文的非ACSII字符,须先进行编码。(java提供了一个native2ascII命令用于编码)
  • 资源文件的内容采用“关键字=值”的形式,软件根据关键字检索值显示在页面上
  • 资源包中的所有资源文件的关键字必须相同,值则为相应国家的文字

举例:

中文资源文件

username=\u7528\u6237\u540d
password=\u5bc6\u7801
submit=\u63d0\u4ea4

英文资源文件

username=username
password=password
submit=submit

二、实现固定文本的格式化     静态数据

2.1、实现固定文本格式化的步骤

1.ResourceBundle类该提供了一个静态方法getBundle,该方法用于装载资源文件,并创建ResourceBundle实例

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

basename为资源包基名(且必须为完整路径)。

2.如果与该locale对象匹配的资源包子类找不到。则选用默认资源文件予以显示。 

3.加载资源文件后, 程序调用ResourceBundle 实例对象的 getString 方法获取指定的资源信息名称所对应的值。

String value =  myResources.getString(“key");

4.在WEB应用中实现固定文本的国际化

2.2、示例

package cn.itcase.locale;

import java.util.Locale;
import java.util.ResourceBundle;

import org.junit.Test;

public class I18n {
	// 国际化 静态数据
	@Test
	public void I18nTest() {
		// 中文语言环境
		Locale le = Locale.CHINA;
		// System.out.println(le.getCountry());

		// 创建工具类对象ResourceBundle
		ResourceBundle bundle = ResourceBundle
				.getBundle("cn.itcase.locale.msg", le);
		
		// 根据key获取配置文件中的值
		System.out.println(bundle.getString("hello"));
		System.out.println(bundle.getString("username"));
		System.out.println(bundle.getString("pwd"));
		System.out.println(bundle.getString("title"));
       System.out.println(bundle.getString("submit"));
	}

}

msg.properties   中文环境

hello=\u4F60\u597D
username=\u7528\u6237\u540D
pwd=\u5BC6\u7801
title=\u767B\u9646\u9875\u9762
submit=\ \u767B\u9646

jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <%
  	ResourceBundle bundle = ResourceBundle.getBundle("cn.itcase.locale.msg",request.getLocale());
  	%>
    <base href="<%=basePath%>">
    
    <title><%=bundle.getString("title") %></title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
   <form name="frmLogin" action="${pageContext.request.contextPath }/admin?method=login" method="post">
  	<table align="center" border="1">
  		<tr>
  			<td><%=bundle.getString("username") %></td>
  			<td>
  				<input type="text" name="userName">
  			</td>
  		</tr>
  		<tr>
  			<td><%=bundle.getString("pwd") %></td>
  			<td>
  				<input type="password" name="pwd">
  			</td>
  		</tr>
  		<tr>
  			<td>
  				<input type="submit" value="<%=bundle.getString("submit") %>">
  			</td>
  		</tr>
  	</table>
  </form>
  </body>
</html>

三、动态数据国际化       动态数据

3.1、概述

  • 程序运行动态产生的数据如:日期,数值,时间,货币等
  • 无法进行简单的分离需要特殊处理
  • Java提供API处理动态数据,位于 java.util 包和 java.text 包中

3.2、Locale类

3.2.1、概述

  • Locale 实例对象代表特定地理位置。
  •  Locale 对象本身不会验证它代表地理位置信息是否正确,只是向本地敏感的类提供国家地区信息,与国际化相关的格式化和解析任务由本地敏感的类去完成
  • 若JDK中的某个类在运行时需要根据 Locale 对象来调整其功能,这个类就称为本地敏感类

3.2.2、示例

package cn.itcase.locale;

import java.util.Locale;

public class LocaleZh {
	public static void main(String[] args) {
		// 模拟中文语言环境
		// Locale le = Locale.CHINA;
		Locale le = Locale.getDefault(); // 当前系统默认的语言环境
		System.out.println(le.getCountry()); // 国家简称
		System.out.println(le.getDisplayCountry()); // 国家名称
		System.out.println(le.getLanguage()); // 语言

		// 模拟美国国家
		Locale us = Locale.US;
		System.out.println(us.getCountry());
		System.out.println(us.getDisplayCountry());
	}
}

3.3、DateFormat 类

3.3.1、概述

  1. 时间/日期格式化输出 、国际化时间/日期   
  2. 可以将一个时间/日期格式化为一个可以表示某个地区的时间/日期字符串输出
  3. 它还定义了一些用于描述日期/时间的显示模式的 int 型的常量;包括FULL, LONG, MEDIUM, DEFAULT, SHORT,实例化DateFormat对象时,可以使用这些常量,控制日期/时间的显示长度

3.3.2、示例

package cn.itcase.locale;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;

import org.junit.Test;

public class I18n {
	

	// 动态数据 时间格式化
	@Test
	public void dataformatTest() {
		/*
		 * 日期
		 * SHORT   19-7-19 
		 * LOGIN   2019年7月19日 
		 * MEDIUM  2019-7-19
		 * FULL    2019年7月19日 星期五
		 * 时间
		 * SHORT    下午10:33
		 * LOGN     下午10时35分44秒
		 * MEDIUM   23:07:43
		 * FULL     下午11时10分18秒 CST
		 * 
		 */
		// 日期格式
		int dateStyle = DateFormat.FULL;
		// 时间格式化
		int timeStyle = DateFormat.FULL;
		// 工具类
		DateFormat df = DateFormat.getDateTimeInstance(dateStyle, timeStyle,
				Locale.CHINA);
		String date = df.format(new Date());
		System.out.println(date);
		/*实例化DataFormat的九中方式
		 * 三种带参数的
		 * 1.getDateInstance(int style, Locale aLocale)
		 * 指定日期显示模式和本地信息来获得DateFormat实例对象,
		 * 该实例对象不处理时间值部分
		 * 
		 * 2.getTimeInstance(int style, Locale aLocale)
		 * 指定时间显示模式和本地信息来获得DateFormat实例对象,
		 * 该实例对象不处理日期值部分。
		 * 
		 * 3.getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)
		 * 以单独指定的日期显示模式、时间显示模式和本地信息
		 * 来获得DateFormat实例对象
		 * 
		 * dataformat对象
		 * format: 将date对象格式化为符合某个本地环境习惯的字符串。
		 * parse:将字符串解析为日期/时间对象
		 * 注意:parse和format完全相反
		 * 
		 * 
		 * DateFormat特点:
		 * DateFormat 对象线程不安全,因此每个线程都应该创建自己的 DateFormat实例对象
		 */
	}

}
/*将字符串"2019-7-19 下午11时10分18秒 CST "反向解析为一个date对象
结果为 Fri Jul 19 23:10:18 CST 2019*/
@Test
	public void DataTest() throws Exception {
		   try {
			// 数据准备 將字符串转化为date对象
				String str = "2019-7-19 下午11时10分18秒 CST ";
				// 创建DateFormat工具类,国际化日期
				DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
						DateFormat.FULL, Locale.getDefault());
			Date d = df.parse(str);
				System.out.println(d);
		} catch (Exception e) {
			e.printStackTrace();
		}
		

	}

3.4、NumberFormat

3.4.1、概述

将一个数值格式化为符合某个国家地区习惯的数值字符串,也可以将符合某个国家地区习惯的数值字符串解析为对应的数值

3.4.2、示例

// 国际化 动态文本 数值
	@Test
	public void NumberFormatTest() {
		/*
		 * NumberFormat对象的方法 format 方法:将一个数值格式化为符合某个国家地区习惯的数值字符串
		 * parse方法:将符合某个国家地区习惯的数值字符串解析为对应的数值。
		 * 
		 * 实例化NumberFormat类提供的参数 1.NumberFormat类实例化时,locale对象可作参数也可不作。
		 * 
		 * 2.getNumberInstance(Locale locale)
		 * 以参数locale对象所标识的本地信息来获得具有多种用途的NumberFormat实例对象。
		 * 
		 * 3.getIntegerInstance(Locale locale)
		 * 以参数locale对象所标识的本地信息来获得处理整数的NumberFormat实例对象。
		 * 
		 * 4.getCurrencyInstance(Locale locale)
		 * 以参数locale对象所标识的本地信息来获得处理货币的NumberFormat实例对象
		 * 
		 * 5.getPercentInstance(Locale locale)
		 * 以参数locale对象所标识的本地信息来获得处理百分比数值的NumberFormat实例对象
		 */
		// 模拟语言环境
		//Locale le = Locale.CHINA;
		 Locale le = Locale.US;
		// 国际化工具类
		// 数值
		// NumberFormat nt = NumberFormat.getNumberInstance(le);//20,000
		// 货币
		 NumberFormat nt = NumberFormat.getCurrencyInstance(le); //¥20,000.00
		// 百分比
		// NumberFormat nt = NumberFormat.getPercentInstance(le); //2,000,000%
		//整数
		//NumberFormat nt = NumberFormat.getIntegerInstance(le); // 20,000
		String str = nt.format(20000);
		System.out.println(str);
	}

3.5、MessageFormat类

3.5.1、概述

  • MessageFormat类用以批量处理一个字符串中的多个国际化相关数据的情况
  • MessageFormat类允许开发人员用占位符替换掉字符串中的敏感数据(即国际化相关的数据)。
  • MessageFormat类在格式化输出包含占位符的文本时,messageFormat类可以接收一个参数数组,以替换文本中的每一个占位符。

模式字符串:

At 12:30 on {0},a hurricance destroyed {1} houses and caused {2} of damage.

                                    占位符

占位符的三种写法

  1. {argumentIndex}: 0-9 之间的数字,表示要格式化对象数据在参数数组中的索引号
  2. {argumentIndex,formatType}: 参数的格式化类型
  3. {argumentIndex,formatType,FormatStyle}: 格式化的样式,它的值必须是与格式化类型相匹配的合法模式、或表示合法模式的字符串。

3.5.2、示例

@Test
	public void MessageFormatTest() throws Exception {
		// 数据参数准备
		String pattern = "on{0},a hurricance destroyed {1} houses and caused "
				+ "{2} of damage.";
		// 实例化MessageFormat对象,并装载相应的模式字符串
		MessageFormat mt = new MessageFormat(pattern, Locale.US);
		// 准备数组
		String datetime = "Jul 3, 2019 12:30 PM";
		Date date = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
				DateFormat.SHORT, Locale.US).parse(datetime);
		Object msgArgs[] = { date, new Integer(99), new Double(1E7) }; // 1E7表示1*10的7次方

		// 执行格式化操作
		String result = mt.format(msgArgs);
		System.out.println(result);
     /*输出结果:on7/3/19 12:30 PM,a hurricance destroyed 99 houses and caused 10,000,000 of damage.*/

	}

 

四、JSTL国际化标签库

4.1、<fmt:setLocale>标签

4.1.1、概述

该标签用于jsp页面中显示的设置用户本地化信息,并将设置的本地信息以Locale对象的形式保存在某个web域中

4.1.2、语法

<fmt:setLocale value=“locale”   [variant=“variant”] [scope=“{page|request..}”]/>

属性名

是否支持EL

类型说明

属性描述

value

true

String或java.util.Locale

指定用户的本地化信息,一个字符串或java.util.Local实例对象。如果是字符串必须包含小写的语言名而后是大写的国家名:zh_CN

variant

true

String

指定创建Locale实例对象时设置的变量部分,它作用于标识开发商或特定浏览器为实现扩展功能而自定义的信息。

scope

 

false

String

指定构造出来的Locale实例对象保存在哪个web作用域中。

4.1.2、示例

<fmt:setLocale value="<%=request.getLocale() %>"/>

4.2、<fmt:setBundle>标签

4.2.1、概述

该标签用于根据<fmt:setLocale>标签设置的本地化信息创建一个资源包(ResourceBundle)实例对象,并将其绑定到一个web域的属性上。

4.2.2、语法

<fmt: setBundle basename=“basename”  [var=“varname”] [scope=“{page|request|session|application}”] />

属性名

是否支持EL

属性类型

属性描述

basename

true

String

指定创建ResourceBundle实例对象的基名。

var

false

String

指定将创建出来的ResourceBundle实例对象保存在web域中的属性名。

scope

false

String

指定将创建出来的ResourceBundle实例对象保存在哪个web作用域中。

4.2.3、示例

<f:setBundle basename="cn.itcase.login.login" var="message" scope="page"/>

4.3、<fmt:message>标签

4.3.1、概述

该标签用于从一个资源包中读取信息并进行格式化输出

4.3.2、语法

<fmt:message key=“messageKey”  [bundle=“resourceBundle”] [var=“varname”] [scope=“page|request|session|application”]   />

属性名

是否支持EL

属性类型

属性描述

key

true

String

指定要输出的信息的关键字。

bundle

true

LocalizationContext

指定ResourceBundle对象在web域中的属性名称。

var

false

String

用于指定格式化输出结果保存到某个web域中的属性名。

scope

false

String

指定将格式化结果保存到哪个web域中。

4.3.3、示例

<fmt:message key="name" bundle="${message}"/>

4.4、日期、数字格式化

  • <fmt:formatDate>
  • <fmt:parseDate>
  • <fmt:formatNumber>
  • <fmt:parseNumber>

4.5、示例

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%--引入jstl国际化与格式化标签库 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  	<!-- 一、设置本地化对象 -->
  	<fmt:setLocale value="${pageContext.request.locale}"/>
  	<!-- 二、设置工具类 -->
  	<fmt:setBundle basename="cn.itcase.locale.msg" var="bundle"/>

    <title><fmt:message key="title" bundle="${bundle}"></fmt:message></title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
  </head>
  
  <body>
  <form name="frmLogin" action="${pageContext.request.contextPath }/admin?method=login" method="post">
  	<table align="center" border="1">
  		<tr>
  			<td><fmt:message key="username" bundle="${bundle}"></fmt:message></td>
  			<td>
  				<input type="text" name="userName">
  			</td>
  		</tr>
  		<tr>
  			<td><fmt:message key="pwd" bundle="${bundle}"></fmt:message></td>
  			<td>
  				<input type="password" name="pwd">
  			</td>
  		</tr>
  		<tr>
  			<td>
  				<input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>">
  			</td>
  		</tr>
  	</table>
  </form>
  </body>
</html>