出处:https://www.cnblogs.com/plan123/p/5639803.html

1

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

2

根据数据的类型不同,国际化分为2类:静态数据国际化和动态数据的国际化。

静态数据,包括 “标题”、“用户名”、“密码”这样的文字数据。

动态数据,包括日期、货币等可以动态生成的数据。

 

国际化涉及到java.util.Locale和java.util.ResourceBundle类。

 

java.util.Locale

A Locale object represents a specific geographical, political, or cultural region.

Locale对象代表了一定的地理、政治、文化区域。

 

java.util.ResourceBundle

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就会把相应的资源返回给你。

JavaWeb国际化 随笔 第1张

1、静态数据国际化

 

静态数据国际化的步骤:

(1).建立资源文件,存储所有国家显示的文本的字符串

    a)文件: .properties

    b)命名:  基础名_语言简称_国家简称.properties

        例如: msg_zh_CN.properties     存储所有中文

            msg_en_US.properties    存储所有英文

(2).程序中获取

    ResourceBundle类,可以读取国际化的资源文件!

    Locale类,代表某一区域,用于决定使用哪一个国际化的资源。

 

1.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.2、ResourceBundle的API

static ResourceBundle getBundle(String baseName,Locale locale) 获取ResourceBundle实例

String getString(String key)    根据key获取资源中的值

 

 

1.3、示例

 

(1)建立properties文件:msg_zh_CN.properties和msg_en_US.properties

msg_zh_CN.properties

1 2 uname=\u59D3\u540D pwd=\u5BC6\u7801

JavaWeb国际化 随笔 第2张

 

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.4、关于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);

 

 

2、动态数据国际化

动态国际化则主要涉及到数字、货币、百分比和日期

例如:

    中文: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);      } }

 

 

 

3、JSP页面国际化

 

数值,货币,时间,日期等数据由于可能在程序运行时动态产生,所以无法像文字一样简单地将它们从应用程序中分离出来,而是需要特殊处理,有的Java培训机构讲的不错。Java 中提供了解决这些问题的 API 类(位于 java.util 包和 java.text 包中)

 

3.1、准备工作:建立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

JavaWeb国际化 随笔 第3张

message_en_US.properties

1 2 3 4 title=Plean Log In uname=User Name pwd=Password submit=Submit\!

 

3.2、使用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.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 >      <!-- 一、设置本地化对象 -->      < fmt:setLocale  value = "${pageContext.request.locale }" />      <!-- 二、设置工具类 -->      < 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 >
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄