1、国际化的概念
Internationalization,国际化,简称i18n【首字母i,中间18个字母,末位n】
国际化指不同国家的人,访问用一个网站,会显示不同国家的语言
国际化一般只支持英文即可
2、国际化的原理
⑴ 通过Locale对象,获取语言及国家信息
⑵ 获取语言和国家信息后,在通过ResourceBundle对象,来加载对应的国际化资源文件
3、相关类
Locale
用来获取语言和国家信息
Locale类中有一些静态的常量,保存了一些语言和国家信息。诸如CHINA,US等
相关方法
public Locale(String language, String country) {}
创建一个Locale对象。需要传入语言和国家的信息
public static Locale getDefault() {}
获取默认的语言和国家信息。静态方法,通过Locale来调用
使用示例
// 获取系统默认的语言和国家信息
Locale defaultLocale = Locale.getDefault();
System.out.println(defaultLocale);
// 创建一个Locale对象
Locale locale = new Locale("zh", "CN");
System.out.println(locale);
// 获取中国的语言和国家信息
Locale china = Locale.CHINA;
System.out.println(china);
// 获取美国的语言和国家信息
Locale us = Locale.US;
System.out.println(us);
ResourceBundle
用来加载国际化资源文件
国际化资源文件
⑴ 创建规则
基础名语言代码国家代码.properties
注意:基础名可以随意起,但是语言代码和国家代码不能随便起
否则使用时会报错: java.util.MissingResourceException: Can’t find bundle for base name res, locale ???
⑵ 存放位置
要放到源码包下【例如src下】
相关方法
public static final ResourceBundle getBundle(String baseName, Locale locale) {}
获取一个ResourceBundle对象。第一个参数baseName需要传入国际化资源文件的基础名;第二个参数locale需要传入语言及国家信息对象
注意:
⑴ 传入的baseName,必须和国际化资源文件名字的基础名对应,否则会报错:java.util.MissingResourceException: Can’t find bundle for base name 【传入的不存在的baseName】, locale 【默认的语言及国家代码】
⑵ 传入的locale,必须和国际化资源文件名字的语言及国家代码要匹配,否则会找系统默认的语言及国家信息
前提是存在系统默认的语言及国家信息,否则会报错:java.util.MissingResourceException: Can’t find bundle for base name res, locale ???
public final String getString(String key) {}
根据key获取在国际化资源文件中对应的value值
注意:传入的key必须在properties中存在,否则会报错:java.util.MissingResourceException: Can’t find resource for bundle java.util.PropertyResourceBundle, key ???
使用示例
【res_zh_CN.properties】
name=\u59D3\u540D
【res_en_US.properties】
name=Name
【测试类】
ResourceBundle chinaRB = ResourceBundle.getBundle("res", Locale.CHINA);
String chinaName = chinaRB.getString("name");
System.out.println(chinaName); // 姓名
ResourceBundle usRB = ResourceBundle.getBundle("res", Locale.US);
String usName = usRB.getString("name");
System.out.println(usName); // Name
DateFormat
用来对日期和时间进行国际化
格式化风格字段
DateFormat提供了一些常量,用来表示格式化风格
// Constant for full style pattern.
public static final int FULL = 0;
// Constant for long style pattern.
public static final int LONG = 1;
// Constant for medium style pattern.
public static final int MEDIUM = 2;
// Constant for short style pattern.
public static final int SHORT = 3;
// Constant for default style pattern. Its value is MEDIUM.【默认值为2】
public static final int DEFAULT = MEDIUM;
相关方法
public final static DateFormat getTimeInstance(int style, Locale aLocale) {}
获取日期格式器,该格式器具有给定语言环境的给定格式化风格。参数一style,需要传入格式化风格,即系统提供的常量字段;参数二aLicale,需要传入指定的语言及国家信息
注意:传入的格式化风格,数值不能小于1或大于3,否则会报错:IllegalArgumentException: Illegal time style ???
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale) {}
获取日期时间格式器,该格式器具有给定语言环境的给定格式化风格。参数一dateStyle,需要传入格式化风格,即系统提供的常量字段;参数二timeStyle,同样需要传入格式化风格;参数三aLocale,需要传入指定的语言及国家信息
注意:传入的格式化风格,数值不能小于1或大于3,否则会报错:IllegalArgumentException: Illegal time style ??? 或 IllegalArgumentException: Illegal date style ???
public final String format(Date date) {}
用指定的格式器,来格式传入的时间
使用示例
Locale aLocale = Locale.CHINA;
DateFormat df = DateFormat.getTimeInstance(DateFormat.FULL, aLocale);
String date = df.format(new Date());
System.out.println(date + "【DateFormat.FULL】");
df = DateFormat.getTimeInstance(1, aLocale);
date = df.format(new Date());
System.out.println(date + "【DateFormat.LONG】");
df = DateFormat.getTimeInstance(2, aLocale);
date = df.format(new Date());
System.out.println(date + "【DateFormat.MEDIUM】");
df = DateFormat.getTimeInstance(DateFormat.DEFAULT, aLocale);
date = df.format(new Date());
System.out.println(date + "【DateFormat.DEFAULT】\n");
df = DateFormat.getTimeInstance(3, aLocale);
date = df.format(new Date());
System.out.println(date + "【DateFormat.SHORT】");
System.out.println("=======================================");
df = DateFormat.getDateTimeInstance(0, 0, aLocale);
date = df.format(new Date());
System.out.println(date);
df = DateFormat.getDateTimeInstance(1, 1, aLocale);
date = df.format(new Date());
System.out.println(date);
df = DateFormat.getDateTimeInstance(2, 2, aLocale);
date = df.format(new Date());
System.out.println(date);
df = DateFormat.getDateTimeInstance(3, 3, aLocale);
date = df.format(new Date());
System.out.println(date);
4、常用的国际化标签【JSTL】
在使用前,需要导入JSTL的jar包,并在JSP页面上使用JSP指令标签导入标签库:
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
设置语言及国家信息
<fmt:setLocale value="" />
value需要传入一个Locale对象
通过ServletRequest获取浏览器优先使用的语言及国家信息
public Locale getLocale();
Tips:在JSP页面中,可以使用JSP的九大隐含对象中的request来获取
设置国际化资源文件的基础名
<fmt:setBundle basename="" />
basename即国际化资源文件名的基础名
根据key获取在国际化资源文件中对应的value
<fmt:message key=""></fmt:message>
key即在国际化资源文件properties中的key
填充国际化资源文件中的占位符
<fmt:param></fmt:param>
国际化资源文件中的占位符
用一对大括号,中间写入下标即可。例如:{0}
name=Welcome {0}!
注意:大括号中的下标从0开始
使用JSTL的标签填充占位符
<fmt:message key="">
<fmt:param></fmt:param>
<fmt:param></fmt:param>
</fmt:message>
只需要在
<fmt:param></fmt:param>
标签的中间写入要填充的内容即可
根据properties文件中占位符的个数,来写多个
<fmt:param>
标签
注意:
⑴ <fmt:param>标签的个数要和properties文件中的{下标}的个数要一致,且要一一对应
⑵ 当<fmt:param>的个数小于{下标}的个数时,会在页面上显示多余的 {下标}
⑶ 当<fmt:param>的个数大于{下标}的个数时,多余的<fmt:prarm>中的文字不会显示
对日期和时间进行格式化
<fmt:formatDate value="" dateStyle="" timeStyle="" type="" />
value即要格式化的Date对象
dateStyle即格式化风格,可以填入full,long,medium,short。一般写full
timeStyle,同dateStyle。一般写full
type即要显示日期(date)还是时间(time),还是日期时间(both)。一般写both
中英文页面【使用示例】
【i18n_zh_CN.properties】
login=\u767B\u5F55
username=\u7528\u6237\u540D
password=\u5BC6\u7801
language1=English
language2=\u4E2D\u6587
locale1=en_US
locale2=zh_CN
info=\u6B22\u8FCE {0} \u767B\u5F55\u7F51\u7AD9\uFF0C\u73B0\u5728\u65F6\u95F4\uFF1A{1}
user=\u7528\u6237
【i18n_en_US.properties】
login=Login
username=Username
password=Password
language1=\u4E2D\u6587
language2=English
locale1=zh_CN
locale2=en_US
info=Welcome {0} to website, now is: {1}
user=User
【login.jsp】
<%@ page import="java.util.Date"%>
<%@ page import="java.util.Locale"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%-- 没有请求参数时 --%>
<c:if test="${empty param.locale}">
<%-- 获取浏览器优先使用的语言及国家信息 --%>
<% Locale locale = request.getLocale(); %>
<%-- 设置语言及国家信息 --%>
<fmt:setLocale value="<%=locale%>"/>
</c:if>
<%-- 有请求参数时 --%>
<c:if test="${not empty param.locale}">
<fmt:setLocale value="${param.locale}"/>
</c:if>
<%-- 设置国际化资源文件的基础名 --%>
<fmt:setBundle basename="i18n"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>
<fmt:message key="login"></fmt:message>
</title>
</head>
<body>
<h1>
<%-- 从国际化资源文件中,获取带有占位符的value --%>
<fmt:message key="info">
<%-- 填充占位符 --%>
<fmt:param>
<font color="red">
<fmt:message key="user"></fmt:message>
</font>
</fmt:param>
<fmt:param>
<%-- 格式化日期时间 --%>
<fmt:formatDate value="<%=new Date()%>" dateStyle="full" timeStyle="full" type="both" />
</fmt:param>
</fmt:message>
</h1>
<form action="" method="post">
<fmt:message key="username"></fmt:message>
<input type="text" /><br /><br />
<fmt:message key="password"></fmt:message>
<input type="password" /><br /><br />
<input type="submit" value='<fmt:message key="login"></fmt:message>' /><br /><br />
</form>
<a href='${pageContext.request.contextPath}/login.jsp?locale=<fmt:message key="locale1"></fmt:message>'>
<fmt:message key="language1"></fmt:message>
</a>
|
<a href='<%=request.getContextPath()%>/login.jsp?locale=<fmt:message key="locale2"></fmt:message>'>
<fmt:message key="language2"></fmt:message>
</a>
</body>
</html>