根据数据的类型不一样,国际化分为2类:静态数据国际化和动态数据的国际化。html
静态数据,包括 “标题”、“用户名”、“密码”这样的文字数据。java
动态数据,包括日期、货币等能够动态生成的数据。node
国际化涉及到java.util.Locale和java.util.ResourceBundle类。面试
java.util.Locale数据库
A Locale object represents a specific geographical, political, or cultural region.app
Locale对象表明了必定的地理、政治、文化区域。jsp
java.util.ResourceBundleide
Resource bundles contain locale-specific objects. When your program needs a locale-specific resource, a String for example, your program can load it from the resource bundle that is appropriate for the current user's locale. In this way, you can write program code that is largely independent of the user's locale isolating most, if not all, of the locale-specific information in resource bundles. 函数
ResouceBundle,由两个单词组成Resouce和Bundle,合在一块儿就是“资源包”的意思。ResouceBundle是包含不一样区域(Locale)资源的集合,只要向ResouceBundle提供一个特定的Locale对象,ResouceBundle就会把相应的资源返回给你。工具
一、静态数据国际化
静态数据国际化的步骤:
(1).创建资源文件,存储全部国家显示的文本的字符串
a)文件: .properties
b)命名: 基础名_语言简称_国家简称.properties
例如: msg_zh_CN.properties 存储全部中文
msg_en_US.properties 存储全部英文
(2).程序中获取
ResourceBundle类,能够读取国际化的资源文件!
Locale类,表明某一区域,用于决定使用哪个国际化的资源。
1.一、Locale的API
static Locale getDefault() 获得JVM中默认的Locale对象
String getCountry() 获得国家名称的简写
String getDisplayCountry() 获得国家名称的全称
String getLanguage() 获得当前语言的简写
String getDisplayLanguage() 获得语言的全称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package
com.rk.i18n.demo;
import
java.util.Locale;
public
class
Demo01
{
public
static
void
main(String[] args)
{
//本地化对象:Locale
// 封装语言、国家信息的对象,由java.util提供
// Locale locale = Locale.CHINA;
// Locale locale = Locale.US;
Locale locale = Locale.getDefault();
String country = locale.getCountry();
String displayCountry = locale.getDisplayCountry();
String language = locale.getLanguage();
String displayLanguage = locale.getDisplayLanguage();
System.out.println(country);
// CN
System.out.println(displayCountry);
// 中国
System.out.println(language);
// zh
System.out.println(displayLanguage);
// 中文
}
}
|
1.二、ResourceBundle的API
static ResourceBundle getBundle(String baseName,Locale locale) 获取ResourceBundle实例
String getString(String key) 根据key获取资源中的值
1.三、示例
(1)创建properties文件:msg_zh_CN.properties和msg_en_US.properties
msg_zh_CN.properties
1
2
|
uname=\u59D3\u540D
pwd=\u5BC6\u7801
|
msg_en_US.properties
1
2
|
uname=User Name
pwd=Password
|
(2)代码获取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package
com.rk.i18n.demo;
import
java.util.Locale;
import
java.util.ResourceBundle;
// 国际化 - 静态数据
public
class
Demo02
{
public
static
void
main(String[] args)
{
// 中文语言环境
Locale locale = Locale.US;
// 建立工具类对象ResourceBundle
ResourceBundle bundle = ResourceBundle.getBundle(
"com.rk.i18n.demo.msg"
, locale);
// 根据key获取配置文件中的值
String uname = bundle.getString(
"uname"
);
String pwd = bundle.getString(
"pwd"
);
//输出
System.out.println(uname);
System.out.println(pwd);
}
}
|
1.四、关于ResourceBundle的资源文件properties
文件命名:基础名、语言简称
Resource bundles belong to families whose members share a common base name, but whose names also have additional components that identify their locales. For example, the base name of a family of resource bundles might be "MyResources". The family can then provide as many locale-specific members as needed, for example a German one named "MyResources_de".
文件命名:国家简称
If there are different resources for different countries, you can make specializations: for example, "MyResources_de_CH" contains objects for the German language (de) in Switzerland (CH). If you want to only modify some of the resources in the specialization, you can do so.
文件命名:默认的Resource Bundle
The family should have a default resource bundle which simply has the same name as its family - "MyResources" - and will be used as the bundle of last resort if a specific locale is not supported.
文件内容:属于同一个family的resource bundle要包含相同的items内容。
Each resource bundle in a family contains the same items, but the items have been translated for the locale represented by that resource bundle. For example, both "MyResources" and "MyResources_de" may have a String that's used on a button for canceling operations. In "MyResources" the String may contain "Cancel" and in "MyResources_de" it may contain "Abbrechen".
Java代码:获取Resource Bundle
When your program needs a locale-specific object, it loads the ResourceBundle class using the getBundle method:
ResourceBundle myResources = ResourceBundle.getBundle("MyResources", currentLocale);
二、动态数据国际化
动态国际化则主要涉及到数字、货币、百分比和日期
例如:
中文:1987-09-19 ¥1000
英文: Sep/09 1987 $100
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package
com.rk.i18n.demo;
import
java.text.DateFormat;
import
java.text.NumberFormat;
import
java.text.ParseException;
import
java.util.Date;
import
java.util.Locale;
import
org.junit.Test;
public
class
Demo03
{
// 国际化 - 动态文本 - 0. 概述
public
void
testI18N()
{
// 国际化货币
NumberFormat.getCurrencyInstance();
// 国际化数字
NumberFormat.getNumberInstance();
// 国际化百分比
NumberFormat.getPercentInstance();
// 国际化日期
// DateFormat.getDateTimeInstance(dateStyle, timeStyle, aLocale)
}
// 国际化 - 动态文本 - 1. 国际化货币
@Test
public
void
testI18NCurrency()
{
// 模拟语言环境
Locale locale = Locale.CHINA;
// 数据准备
double
number =
100
;
// 工具类
NumberFormat nf = NumberFormat.getCurrencyInstance(locale);
// 国际化货币
String str = nf.format(number);
// 输出
System.out.println(str);
}
//面试题: 代码计算: $100 * 10
@Test
public
void
testCurrency()
throws
ParseException
{
String str =
"$100"
;
int
num =
10
;
// 1. 分析str值是哪一国家的货币
Locale locale = Locale.US;
// 2. 国际化工具类
NumberFormat nf = NumberFormat.getCurrencyInstance(locale);
// 3. 解析str
Number number = nf.parse(str);
//4.进行计算
int
value = number.intValue() * num;
//5.格式化输出
str = nf.format(value);
System.out.println(str);
}
// 国际化 - 动态文本 - 2. 国际化数值
@Test
public
void
testI18NNumber()
{
Locale locale = Locale.CHINA;
NumberFormat nf = NumberFormat.getNumberInstance(locale);
String str = nf.format(
1000000000
);
System.out.println(str);
}
// 国际化 - 动态文本 - 3. 国际化百分比
@Test
public
void
testI18NPercent()
{
Locale locale = Locale.CHINA;
NumberFormat nf = NumberFormat.getPercentInstance(locale);
String str = nf.format(
0.325
);
System.out.println(str);
}
// 国际化 - 动态文本 - 4. 国际化日期
/*
* 日期
* FULL 2015年3月4日 星期三
* LONG 2015年3月4日
* FULL 2015年3月4日 星期三
* MEDIUM 2015-3-4
* SHORT 15-3-4
*
* 时间
* FULL 下午04时31分59秒 CST
* LONG 下午04时32分37秒
* MEDIUM 16:33:00
* SHORT 下午4:33
*
*
*/
@Test
public
void
testI18NDate()
{
int
dateStyle = DateFormat.FULL;
int
timeStyle = DateFormat.FULL;
Locale locale = Locale.CHINA;
DateFormat df = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
String date = df.format(
new
Date());
System.out.println(date);
}
// 面试2: 请将时间值:09-11-28 上午10时25分39秒 CST,反向解析成一个date对象。
@Test
public
void
testDate()
throws
ParseException
{
String str =
"09-11-28 上午10时25分39秒 CST"
;
int
dateStyle = DateFormat.SHORT;
int
timeStyle = DateFormat.FULL;
Locale locale = Locale.CHINA;
// 建立DateFormat工具类,国际化日期
DateFormat df = DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale);
Date date = df.parse(str);
System.out.println(date);
}
}
|
三、JSP页面国际化
数值,货币,时间,日期等数据因为可能在程序运行时动态产生,因此没法像文字同样简单地将它们从应用程序中分离出来,而是须要特殊处理,有的Java培训机构讲的不错。Java 中提供了解决这些问题的 API 类(位于 java.util 包和 java.text 包中)
3.一、准备工做:创建properties资源
创建2个properties文件:message_en_US.properties和message_zh_CN.properties。
message_zh_CN.properties
1
2
3
4
|
title=\u4F60\u597D\uFF0C\u8BF7\u767B\u5F55
uname=\u7528\u6237\u540D
pwd=\u5BC6\u7801
submit=\u63D0\u4EA4
|
message_en_US.properties
1
2
3
4
|
title=Plean Log In
uname=User Name
pwd=Password
submit=Submit\!
|
3.二、使用JSP脚本进行国际化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
<
head
>
<%
ResourceBundle bundle = ResourceBundle.getBundle("com.rk.i18n.resource.message", request.getLocale());
%>
<
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"
>
</
head
>
<
body
>
<
table
border
=
"1"
>
<
tr
>
<
td
><%=bundle.getString("uname") %></
td
>
<
td
><
input
type
=
"text"
name
=
"uname"
/></
td
>
</
tr
>
<
tr
>
<
td
><%=bundle.getString("pwd") %></
td
>
<
td
><
input
type
=
"password"
name
=
"pwd"
/></
td
>
</
tr
>
<
tr
>
<
td
></
td
>
<
td
><
input
type
=
"submit"
value
=
"<%=bundle.getString("
submit") %>"/></
td
>
</
tr
>
</
table
>
</
body
>
</
html
>
|
3.三、使用JSTL进行国际化
JSTL标签:
核心标签库
国际化与格式化标签库
数据库标签库(没用)
函数库
<fmt:setLocale value=""/> 设置本地化对象
<fmt:setBundle basename=""/> 设置工具类
<fmt:message></fmt:message> 显示国际化文本
格式化数值:<fmt:formatNumber pattern="#.##" value="100.99"></fmt:formatNumber>
格式化日期:<fmt:formatDate pattern="yyyy-MM-dd" value="${date}"/>
须要注意的一点是:HttpServletRequest有一个方法是getLocale(),能够获取当前request中的Locale信息,在EL表达式中能够使用${pageContext.request.locale}获取
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
<%@ 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
>
<!-- 1、设置本地化对象 -->
<
fmt:setLocale
value
=
"${pageContext.request.locale }"
/>
<!-- 2、设置工具类 -->
<
fmt:setBundle
basename
=
"com.rk.i18n.resource.message"
var
=
"msg"
/>
<
title
><
fmt:message
bundle
=
"${msg }"
key
=
"title"
></
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
>
<
table
border
=
"1"
>
<
tr
>
<
td
><
fmt:message
bundle
=
"${msg }"
key
=
"uname"
></
fmt:message
></
td
>
<
td
><
input
type
=
"text"
name
=
"uname"
/></
td
>
</
tr
>
<
tr
>
<
td
><
fmt:message
bundle
=
"${msg }"
key
=
"pwd"
></
fmt:message
></
td
>
<
td
><
input
type
=
"password"
name
=
"pwd"
/></
td
>
</
tr
>
<
tr
>
<
td
></
td
>
<
td
><
input
type
=
"submit"
value
=
"<fmt:message bundle="
${msg }"
key
=
"submit"
></
fmt:message
>"/></
td
>
</
tr
>
</
table
>
</
body
>
</
html
>
|
格式化数值和日期
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
html
>
<
head
>
<
title
>格式化</
title
>
<
meta
http-equiv
=
"pragma"
content
=
"no-cache"
>
<
meta
http-equiv
=
"cache-control"
content
=
"no-cache"
>
<
meta
http-equiv
=
"expires"
content
=
"0"
>
<
body
>
<!--
格式化金额
格式: 0.00 保留2为小数,会自动补0
#.## 保留2为小数,不自动补0
-->
<
fmt:formatNumber
pattern
=
"0.00"
value
=
"100"
></
fmt:formatNumber
> <
br
>
<
fmt:formatNumber
pattern
=
"#.##"
value
=
"100"
></
fmt:formatNumber
> <
br
>
<
fmt:formatDate
pattern
=
"yyyyMMdd"
value="<%=new Date() %>"/> <
br
>
<%
request.setAttribute("date", new Date());
%>
<
fmt:formatDate
pattern
=
"yyyy-MM-dd"
value
=
"${date }"
/> <
br
>
</
body
>
</
html
>
|