17.EL表达式(我的JavaEE笔记)

一、EL表达式简介

1.EL全名为Expression Language。主要作用:

  • 获取数据:EL表达式主要用于替换jsp页面中的脚本表达式,以从各种类型的web域中检索java对象,获取数据。(某个web域中的对象,访问javaBean的属性、访问list集合,访问map集合、访问数组)
  • 执行运算:利用EL表达式可以在jsp页面中执行一些基本的关系运算、逻辑运算和算数运算,以在jsp页面中完成一些简单的逻辑运算。${user==null}
  • 获取web开发常用对象:EL表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
  • 调用java方法:EL表达式允许用户开发自定义EL函数,以在jsp页面中通过EL表达式调用java类的方法。

2.获取数据(在前面的入门中已经讲过)

  • 使用EL表达式获取数据的语法:${标识符}
  • EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、Application四个域中查找相应的对象,找到则返回相应的对象,找不到则返回“”(不是null)。
  • EL表达式可以很轻松获取javaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
    ${user.address.city}
    ${user.list[0]}:访问有序集合某个位置的元素
    ${map.key}:获得map集合中指定key的值
  • 结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,如:迭代数组、迭代collection类型集合、迭代map类型集合。
    相关代码:(工程el_example
    1.jsp
<%@page import="cn.itcast.Person"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>EL表达式获取数据</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">

  </head>
  
  <body>
    <%
        request.setAttribute("name", "aaa");
     %>
     ${name }<%--翻译成pageContext.findAttribute("name"); --%>
     <br>
     <!-- 在JSP页面中,使用EL表达式获得bean的属性 -->
     <%
        Person person = new Person();
        person.setAge(12);
        request.setAttribute("person", person);
      %>
      ${person.age }
      <br>
      <!-- 获取list集合中指定位置的数据 -->
      <%
        Person p1 = new Person();
        p1.setName("aaa");
        
        Person p2 = new Person();
        p1.setName("bbb");
        
        List list = new ArrayList();
        list.add(p1);
        list.add(p2);
        request.setAttribute("list", list);
       %>
       ${list[1].name}
       
       <!-- 迭代集合 -->
       <c:forEach var="person" items="${list }">
            ${person.name}
       </c:forEach>
       <br>
       <!-- 在jsp页面中,使用EL表达式获取map集合的数据 -->
       <%
            Map map = new HashMap();
            map.put("a", "aaa");
            map.put("b", "bbb");
            map.put("c", "ccc");
            map.put("1", "111");
            request.setAttribute("map", map);
        %>
        ${map.c }<!-- 根据关键字取map集合的数据 --><br>
        
        ${map["1"]}<br>
        <c:forEach var="me" items="${map}">
            ${me.key} = ${me.value }
        </c:forEach>
        
  </body>
</html>

注意:使用EL表达式表达式取得数据时一般都用“.”运算符,如果取不出来再使用“[]”运算符,比如Map的关键字是数字则需要使用[]。

3.执行运算

  • 语法:${运算表达式},EL表达式支持如下运算符:
逻辑运算符.png
关系运算符.png
  • empty运算符:检查对象是否为null或空。

2.jsp

    <% 
        List list = null;
        //List list = new ArrayList();
        //list.add("a");
        //list.add("b");
        
        request.setAttribute("list",list);
    %>
    <c:if test="${!empty(list)}">
        <c:forEach var="str" items="${list}">
            ${str }
        </c:forEach>
    </c:if>
    
    <c:if test="${empty(list)}">
        对不起,没有您想看的数据
    </c:if>
  • 二元表达式:${user!=null?user.name:""}
    使用场景:

2.jsp

     <%
        session.setAttribute("user", new User("vvv"));
      %>
      ${user==null?"对不起,您还没有登录":user.username }
      
      <%
        User user = new User();
        user.setGender("male");
        request.setAttribute("user", user);
       %>
       <input type="radio" name="gender" ${user.gender=='male'?'checked':''}>男
       <input type="radio" name="gender" ${user.gender=='female'?'checked':''}>女
       
       <!-- 下面这个例子这里还未完成,需要用到后面讲到的函数,这里只是举例,后面再说 -->
       <%
            user = new User();
            String likes[] = {"sing","dance","football"};
            user.setLikes(likes);
            request.setAttribute("user", user); 
        %>
        <input type="checkbox" name="like" value="sing">唱歌
        <input type="checkbox" name="like" value="dance">跳舞
        <input type="checkbox" name="like" value="basketball">篮球
        <input type="checkbox" name="like" value="football">足球

说明:二元表达式在以后的开发中用的很多。第一个是登录场景我们需要判断用户是否登录;第二个和第三个场景都是用户注册时一次注册失败,我们需要回显用户的一部分信息。如果某个用户的爱好中包含某项,我们需要选中某项,此时我们还完成不了,需要使用后面讲到的EL函数才能搞定,这里先放在这里。

4.获得web开发常用对象

  • EL表达式语言中定义了11个隐式对象,使用这些隐式对象可以很方便地获取web开发中的一些常用的对象,并读取这些对象的数据。
  • 语法:${隐式对象名称}:获得对象的引用
1.png
2.png
  • 之前我们说过,在使用EL表达式取得某个属性的值${name}时会将这个标签语句翻译成pageContext.findAttribute("name");,但是其实在翻译之前是需要先判断这个name属性是不是EL定义的十一个隐式对象,如果不是才翻译,否则直接返回隐式对象的引用。
  • 这里注意,EL表达式中只定义了JSP中隐式对象中的pageContext对象,这是因为我们可以通过pageContext对象获得其他八个隐式对象。

从相关的域中取得相应的值:

  • 1.从相关域中查找数据

3.jsp

<body>
    <!-- 从page域中查找数据 -->
    <%
        pageContext.setAttribute("aaa", "aaa");
     %>
     ${pageScope.aaa }

     <!--从request域中取得数据  -->
     <%
        request.setAttribute("bbb", "bbb");
      %>
      ${requestScope.bbb }

      <!-- 从session域中取得数据,如检查用户是否登录-->
      ${sessionScope.user}

      <!-- 从application域中取得数据这里就不再给例子了 -->
  </body>

这里我们可以看到我们可以分别从不同的域中取得数据。

  • 2.其他隐含对象

3.jsp

      <!-- 获得用于保存请求参数map,并从map中获取数据 -->
      <!-- 试验地址是:http://localhost:8080/el_example/3.jsp?name=aaa -->
      ${param.name}
      
      <br>-----------------------<br>
      <!-- 此表达式会经常用在数据回显上 -->
      <form action="${pageContext.request.contextPath}/servlet/RegisterServlet" method="post">
        <input type="text" name="username" value="${param.username }"><!-- 以前是这样写的:value="${formbean.username}" -->
        <input type="submit" value="注册">
      </form>
      
      <br>----------paramValues获得请求参数-------------<br>
      <!-- 试验地址是:http://localhost:8080/el_example/3.jsp?like=aaa$like=bbb -->
      ${paramValues.like[0]}
      ${paramValues.like[1]}
      
      <br>----------header获得请求头-------------<br>
      ${header.Accept}
      ${header["Accept-Encoding"]}
      
      <br>----------获取客户机提交的cookie-------------<br>
      <!-- 从cookie隐式对象中根据名称获得的是cookie对象,要想获得值,还需要使用.value -->
      ${cookie.JSESSION.value}//保存所有cookie的map
      
      <br>----------获取web应用初始化参数-------------<br>
      ${initParam.xxx }//servletContext中用于保存初始化参数的map
      ${initParam.root }

说明:对于param对象来说,是用来保存请求参数的map,因为一般jsp不处理业务逻辑,所以此对象一般用在数据回显上面。在回显的时候我们就不需要FormBean对象了。同时我们这里知道request中至少存在两个map,一个是set进request中的,一个是请求参数的map。

5.使用EL调用java方法

  • EL表达式语法允许开发人员开发自定义函数,以调用java类的方法。
    如:${prefix:method(params)}
    在EL表达式中调用的只能是java类的静态方法。
    这个java类的静态方法需要在tld文件中描述,才可以被EL表达式调用。
    EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通java程序代码所能完成的功能。

  • EL函数开发步骤
    一般来说,EL自定义函数开发与应用包括以下三个步骤:
    1.编写一个java类的静态方法
    2.编写标签库描述符(tld)文件,在tld文件中描述自定义函数。
    3.在jsp页面中导入和使用自定义函数

示例:开发对html标签转义的EL函数
相关代码:
itcast.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee web-jsptaglibrary_2_1.xsd">
 <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>/itcast</uri>
    
    <function>
        <name>filter</name>
        <function-class>cn.itcast.HtmlFilter</function-class>
        <function-signature>java.lang.String filter(java.lang.String)</function-signature>
    </function>
</taglib>

4.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/WEB-INF/itcast.tld" prefix="fn" %>

![
![
![保留关el键字.png](http://upload-images.jianshu.io/upload_images/1925650-fb15f34a9aec2bb0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](http://upload-images.jianshu.io/upload_images/1925650-b1bedb52408a6d26.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](http://upload-images.jianshu.io/upload_images/1925650-039cc3220b91a41d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>EL表达式调用java函数</title>
    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
  </head>
  
  <body>

     ${fn:filter("<a href='#'>链接</a>")}
  </body>
</html>

HtmlFilter.java

package cn.itcast;
import java.util.List;
public class HtmlFilter {
     public static String filter(String message) {

            if (message == null)
                return (null);

            char content[] = new char[message.length()];
            message.getChars(0, message.length(), content, 0);
            StringBuffer result = new StringBuffer(content.length + 50);
            for (int i = 0; i < content.length; i++) {
                switch (content[i]) {
                case '<':
                    result.append("<");
                    break;
                case '>':
                    result.append(">");
                    break;
                case '&':
                    result.append("&");
                    break;
                case '"':
                    result.append(""");
                    break;
                default:
                    result.append(content[i]);
                }
            }
            return (result.toString());

        }
}

说明:

  • 这里我们可以发现我们可以使用EL函数替换掉java代码,那么我们在去掉jsp中的java代码时到底是使用EL函数还是EL标签呢?这里先需要知道的是我们在使用EL标签的时候jsp是将pageContext对象传递进去了的,但是EL函数不涉及到任何传递对象。也就是说EL函数只能移除那些与web开发无关的java代码。自定义标签可以移除所有java代码。
  • 还需要知道我们一般在使用EL函数的时候这样申明:
<%@taglib uri="/WEB-INF/itcast.tld" prefix="fn" %>

,而同时需要注意java方法的申明

<function-signature>java.lang.String filter(java.lang.String)</function-signature>

如果有基本数据类型的参数,可以这样写:

<function-signature>java.lang.String filter(java.lang.String, int[])</function-signature>
  • 注意:EL表达式中不能嵌套EL表达式,我们如果有个List对象要传递进去,应该这样:
<%
  List list = new ArrayList();
  list.add("a");
  request.setAttribute("list", list);
%>
${fn:filter("<a href='#'>链接</a>", list)}

同时如果不能使用EL表达式,请一定加上isELIgnored="false"这个配置。同时在新版的MyEclipse中已经将JSTL相关的jar包导入了,如果是在其他IDE中请查看是否导入了依赖包,如果没有,请导入javax.servlet.jsp.jstl.jarjstl-impl-1.2.2.jar这两个依赖包。

6.EL表达式保留关键字

el保留关键字.png

二、EL函数库

2.1 简介

sun公司自己开发了一套EL函数库,这些函数在JSTL开发包中进行描述,因此在JSP页面中使用sun公司的EL函数库,需要导入JSTL开发包,并在页面中导入EL函数库,如下所示:

<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

注意:在MyEclipse中不需要导入上述的包,同时JSTL包中供包含5个部分的包:核心包(c.tld)、国际化包(fnt.tld)、数据库包(sql.tld)、xml(x.tld)、函数库包(fn.tld),而数据库包和xml包由于jsp页面中一般不能含有java代码,所以这两个包一般不用。而函数库包中我们可以查看tld文件查看其中定义的函数有哪些。

2.2 相关函数(5.jsp)

    1. fn:toLowerCase
      此函数将一个字符串中包含的所有字符转换为小写形式,并返回转换后的字符串,它接收一个字符串类型的参数。例:
${fn:toLowerCase("AAA") }//输出aaa
  • 2.fn:toUpperCase
    此函数将一个字符串中包含所有字符串转换为大写形式,并返回转换后的字符串,它接收一个字符串类型的参数,和上一个函数类似。

  • 3.fn:trim
    此函数删除一个字符串的收尾的空格,并返回删除空格后的结果字符串,它接收一个字符串类型的参数。需要注意的是,此函数不能删除字符串中中间位置的空格。

  • 4.fn:length
    此函数返回一个集合或数组大小,或返回一个字符串中包含的字符的个数,返回值为int类型。接收一个参数,这个参数可以是<c:forEach>标签的items属性支持的任何类型,包括任意类型的数组、java.util.Collection、java.util.Iterator、java.util.Enumeration、java.util.Map等类的实例对象和字符串。如果fn:length函数的参数为null或者是元素个数为0的集合或数组对象,则函数返回0;如果参数是空字符串,则函数返回0。例:

<%
        List list = Arrays.asList("1","2","3");
        request.setAttribute("list", list);
     %>
     ${fn:length(list)}
     ${fn:length("aaa")}
  • 5.fn:split
    此函数以指定字符作为分割符,将一个字符串分割成字符串数组。接收两个字符串类型的参数,第一个参数表示要分割的字符串,第二个参数表示作为分割符的字符。例:
${fn:split("aaa.bbb.ccc",".")[1]}
  • 6.fn:join
    此函数一个字符作为分割符,将一个字符串数组中的所有元素合并为一个字符串并返回合并后的结果字符串。接收两个参数,第一个参数是要操作的字符串数组,第二个参数是作为分割符的字符。若第二个参数是空字符,则函数的返回值直接将元素连接起来。如:假设stringArray是保存在web域中的一个属性,它表示一个值为{"www","it315","org"}的字符串数组,则fn:join(stringArray,".")返回www.it315.org
    fn:join(fn:split("www","it315","org",","),".")的返回值为www.it315.org

  • 7.fn:indexOf
    此函数返回指定字符串在一个字符串中第一次出现的索引值,返回值为int类型。接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,那么,不管第二个参数字符串在第一个参数字符串中出现几次,函数总是返回第一次出现的索引值。如果第一个参数中不包括第二个参数,则函数返回-1;如果第二个参数为空字符串,在返回0。如:fn:indexOf(www.it315.org,"t3")返回值为5。

  • 8.fn:contains
    此函数检测一个字符串中是否包含指定的字符串,返回值为布尔类型。接收两个字符串参数。如果第一个参数字符串中包含第二个参数字符串,则返回true,否则返回false。还有一个忽略大小写的EL函数:fn:containsIgnoreCase,使用方法和上述函数一样,只是不区分大小写。例:

<br>---------完成之前那个回显数据的功能------------<br>
     <%
            User user = new User();
            String likes[] = {"sing","dance","football"};
            user.setLikes(likes);
            request.setAttribute("user", user); 
      %>
      <input type="checkbox" name="like" value="sing" ${fn:contains(fn:join(user.likes, ","),"sing")?'checked':'' }>唱歌
      <input type="checkbox" name="like" value="dance" ${fn:contains(fn:join(user.likes, ","),"dance")?'checked':'' }>跳舞
      <input type="checkbox" name="like" value="basketball" ${fn:contains(fn:join(user.likes, ","),"basketball")?'checked':'' }>篮球
      <input type="checkbox" name="like" value="football" ${fn:contains(fn:join(user.likes, ","),"football")?'checked':'' }>足球
  • 9.fn:startsWith
    此函数用于检测一个字符串是否以指定字符串开始的,返回值为布尔类型。接收两个字符串类型的参数,如果第一个参数字符串以第二个字符串开始,则返回true,否则返回false,与之对应的函数是:fn:endsWith

  • 10.fn:replace
    此函数将一个字符串中包含的指定子字符串替换为其它的指定字符串,并返回替换后的结果字符串。接收三个字符串参数,第一个参数表示要操作的源字符串,第二个参数表示源字符串中要被替换的子字符串,第三个参数表示要被替换成的字符串。如:fn:replace(www.it315.org,",",".")的返回值为字符串www.it315.org

  • 11.fn:substring
    此函数用于截取一个字符串的子字符串并返回截取到的子字符串。接收三个参数,第一个参数是用于指定要操作的源字符串,第二个参数是用于指定截取子字符串开始的索引值,第三个参数是用于指定截取子字符串结束的索引值,第二个参数和第三个参数都是int类型,其值都是从0开始。如:fn:substring(www.it315.org,4,9)的返回值是字符串“it315”,从第5个字符开始到第10个字符结束,但是不包括第10个字符。

  • 12.fn:substringAfter
    此函数用于截取并返回一个字符串的指定子字符串第一次出现之后的子字符串。接收两个字符串类型的参数,第一个参数表示要操作的源字符串,第二个参数表示指定的子字符串。如:fn:substringAfter("www.it315.org",".")的返回值是“it315”。与之对应的函数是fn:substringBefore

  • 13.fn:secapeXml
    此函数和之前我们自己定义的转义函数一样,都是对脚本进行转义。例:

${fn:escapeXml("<a href='#'>链接</a>")}

三、国际化开发

3.1简介

  • 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。

  • 国际化又称为i18n:internationalization

  • 合格的国际化软件
    软件实现国际化,需要具备哪些特征:1.对于程序中固定使用的文本元素,例如菜单栏、导航条使用的文本元素、或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不同语言的文本为之服务。2.对于程序动态产生的数据,例如日期、货币等,软件应能根据当前所在的国家或地区的文化习惯进行显示。

3.2固定文本元素的国际化

  • 1.对于软件中的菜单栏、导航条、错误提示信息,状态信息等这些固定不变的文本信息,可以把它们写在同一个Properties文件中,并根据不同的国家编写不同的Properties文件。这一组Properties文件称之为一个资源包。

  • 2.在javaAPI中提供了一个ResourceBundle类用于描述一个资源包,并且提供了相应的方法getBundle,这个方法可以根据来访者的国家地区自动获取与之对应的资源文件予以显示。

  • 3.一个资源包中的每个资源文件都必须拥有共同的基名。除了基名,每个资源文件的名称中还必须有标识其本地信息的附加部分。如:一个资源包的基名是myproperties,则中文、英文环境相对应的资源文件名则为:
    myproperties_zh.properties、myproperties_en.properties。

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

  • 5.资源文件的书写格式:资源文件的内容通常采用“关键字=值”的形式,软件根据关键字检索值显示在页面上。一个资源包中的所有资源文件的关键字必须相同,值则为相应的文字。并且资源文件中采用的是Properties格式文件,所以文件中的所有字符都必须是ASCII码,对于中文这样的非ASCII字符,须先进行编码。(java提供了一个native2ascii命令用于编码)。如:
    在cn.itcast.resource包中有三个配置文件:myproperties.properties(默认配置文件)、myproperties_zh.properties(中文配置文件)、myproperties_en.properties(英文配置文件)。其中英文配置文件和默认配置文件一样。都是:(工程el_example)
    cn.itcast.resource

英文:
username=username
password=password
submit=submit
中文
username=用户名
password=密码
submit=提交

说明:在MyEclipse中我们直接输入中文会自动帮我们编码。

3.3 编程实现固定文本的国际化

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

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

  • 在web应用中实现固定文本的国际化
    cn.itcast.i18n.Demo1.java

package cn.itcast.i18n;
import java.util.Locale;
import java.util.ResourceBundle;

public class Demo1 {
    public static void main(String[] args){
        //创建实例
        //如果与该locale对象匹配的资源包子类找不到,一般情况下,则选用默认资源文件予以显示
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.myproperties", Locale.US);
        
        //获取配置文件中的相关信息
        String username = bundle.getString("username");
        String password = bundle.getString("password");
        
        System.out.println(username);
        System.out.println(password);
    }
}

login.jsp

<body>
    <%
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.myproperties", request.getLocale());
     %>
     <form action="">
        <%=bundle.getString("username")%> <input type="text" name="username"/><br>
        <%=bundle.getString("password")%> <input type="password" name="password"/><br>
        <input type="submit" value="<%=bundle.getString("submit")%>" />
     </form>
  </body>

这里需要注意资源文件的名字写法,只写基名。当然我们还可以使用标签实现国际化。

<fmt:setBundle var="bundle" basename="cn.itcast.resource.myproperties" scope="page" />
     <form action="">
        <fmt:message key="username" bundle="${bundle}"/> <input type="text" name="username"/><br>
        <fmt:message key="password" bundle="${bundle}"/> <input type="password" name="password"/><br>
        <input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>" />
     </form>

3.4动态数据的国际化

  • 数值、货币、时间、日期等数据由于可能在程序运行时动态产生,所以无法像文字一样简单地将它们从应用程序中分离出来,而是需要特殊处理。Java提供了相应的类(java.util和java.text)

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

3.5 DateFormat类(国际化日期)

  • DateFormat类可以将一个日期/时间对象格式化为表示某个国家地区的日期/时间字符串。

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

  • 例如,对于日期/时间“2005年9月15日下午4时41分20秒”,如设置了DateFormat的显示模式,则日期/时间显示样式分别为:
    SHORT模式完全是数字的,在中文环境下显示为“05-9-15 下午4:41”;在英文环境下为“9/15/05 4:41 PM”
    MEDIUM模式比SHORT模式长些,在中文环境显示为“2005-9-15 16:41:20”;在英文环境下显示为“Sep 15, 2005 4:41:20 PM”
    LONG模式比MEDIUM模式更长一些,在中文环境下显示为“2005年9月15日 下午04时41分20秒”;在英文环境下显示为“September 15, 2005 4:41:20 PM CST”
    FULL模式指定日期/时间的完整格式,在中文环境下显示为“2005年9月15日 星期四 下午04时41分20秒 CST”;在英文环境下,这个日期/时间显示为“Thursday, September 15, 2005 4:41:20 PM CST”

3.6 实例化DateFormat类

3.6.1 实例化DateFormat类

实例化DateFormat类有九种方式,以下三种为带参数形式,下面列出的三种方式也可以分别不带参,或只带显示样式参数。

  • getDateInstance(int style, Locale aLocale):以指定的日期显示模式和本地信息来获得DateFormat实例对象,该实例对象不处理时间值部分。
  • getTimeInstance(int style, Locale aLocale):以指定的时间显示模式和本地信息来获得DateFormat实例对象,该实例对象不处理日期值部分。
  • getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):以单独指定的日期显示模式、时间显示模式和本地信息来获得DateFormat实例对象。

3.6.2 DateFormat对象的方法

  • format:将date对象格式化为符合某个本地环境习惯的字符串。
  • parse:将字符串解析为日期/时间对象
    注意:parse和format完全相反,parse方法在使用时解析的时间或日期要符合指定的国家、地区格式,否则会抛出异常。
  • DateFormat对象通常不是线程安全的,每个线程都应该创建自己的DateFormat实例对象。

Demo2.java

package cn.itcast.i18n;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;

public class Demo2 {
    public static void main(String[] args) throws ParseException{
        Date date = new Date();//当前这一刻的时间(日期、时间)
        
        //输出日期部分
        DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, Locale.GERMAN);
        String result = df.format(date);
        System.out.println(result);
        
        //输出时间部分
        df = DateFormat.getTimeInstance(DateFormat.FULL, Locale.CHINA);
        result = df.format(date);
        System.out.println(result);
        
        //输出日期和时间,其中第一个参数是dateStyle,第二个参数是timeStyle
        df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.CHINA);
        result = df.format(date);
        System.out.println(result);
        
        //把字符串反向解析成一个date对象
        String s = "10-9-26 下午02时49分53秒";
        df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, Locale.CHINA);
        Date d = df.parse(s);
        System.out.println(d);
    }
}

3.7 NumberFormat类

此类可以将一个数值格式化为符合某个国家地区习惯的数值字符串,也可以反过来解析。同样也有format和parse两个方法。实例化NumberFormat类时,可以使用locale对象作为参数,也可以不使用,下面列出的是使用参数的。

  • getNumberInstance(Locale locale):以参数locale对象所标识的本地信息来获得具有多种用途的NumberFormat实例对象
  • getIntegerInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理整数的NumberFormat实例对象
  • getCurrencyInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理货币的NumberFormat实例对象
  • getPercentInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理百分比数值的NumberFormat实例对象

Demo3.java

package cn.itcast.i18n;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;

public class Demo3 {
    public static void main(String[] args) throws ParseException{
        int price = 89;
        
        NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CHINA);
        String result = nf.format(price);
        System.out.println(result);
        
        String s = "¥89.00";
        nf = NumberFormat.getCurrencyInstance(Locale.CHINA);
        Number n = nf.parse(s);
        System.out.println(n);//输出89
        System.out.println(n.doubleValue() + 1);//输出90.0
        
        double num = 0.5;
        nf = NumberFormat.getPercentInstance();
        System.out.println(nf.format(num));
    }
}

3.8 MessageFormat(动态文本)

  • 如果一个字符串中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理。如:
    At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage, 以上字符串中包含了时间、数字、货币等多个与国际化相关的数据,对于这种字符串,可以使用MessageFormat类对其国际化相关的数据进行批量处理。

  • 那此类是如何进行批量处理的?
    1.MessageFormat类允许开发人员用占位符替换掉字符串中的敏感数据(即国际化相关的数据)。
    2.MessageFormat类在格式化输出包含占位符的文本时,messageFormat类可以接收一个参数数组,以替换文本中的每一个占位符。
    模式字符串:
    On {0}, a hurricance destroyed {1} houses and caused {2} of damage
    MessageFormat类的方法:
    MessageFormat(String pattern):实例化MessageFormat对象,并装载相应的模式字符串。
    format(object[] obj):格式化输出模式字符串,参数数组中指定占位符相应的替换对象。

Demo4.java

package cn.itcast.i18n;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

public class Demo4 {
    public static void main(String[] args) throws ParseException{
        String pattern = "On {0}, a hurricance destroyed {1} houses and caused {2} of damage.";
        MessageFormat mf = new MessageFormat(pattern, Locale.CHINA);
        Object arr[] = {new Date(), 99, 100000};
        
        String result = mf.format(arr);
        System.out.println(result);
    }
}
  • 占位符有三种写法
    1.{argumentIndex}: 0-9 之间的数字,表示要格式化对象数据在参数数组中的索引号
    2.{argumentIndex,formatType}: 参数的格式化类型
    3.{argumentIndex,formatType,FormatStyle}: 格式化的样式,它的值必须是与格式化类型相匹配的合法模式、或表示合法模式的字符串。

Demo5.java

package cn.itcast.i18n;
import java.text.MessageFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;

public class Demo5 {
    public static void main(String[] args) throws ParseException{
        String pattern = "At {0, time, short} on {0, date}, a hurricance destroyed {1} houses and caused {2, number, currency} of damage.";
        MessageFormat mf = new MessageFormat(pattern, Locale.US);
        Object arr[] = {new Date(), 99, 100000};
        
        String result = mf.format(arr);
        System.out.println(result);
        
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.myproperties", Locale.CHINA);
        pattern = bundle.getString("message");
        mf = new MessageFormat(pattern, Locale.CHINA);
        arr = new Object[]{new Date(), 99, 100000};
        result = mf.format(arr);
        System.out.println(result);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 一、EL表达式简介 EL 全名为Expression Language。EL主要作用: 获取数据:EL表达式主要用...
    暗香抚动阅读 1,364评论 1 3
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,293评论 18 399
  • 1.什么是JSP (1)jsp全称是Java Server Pages,它和Servlet技术一样都是sun公司定...
    yjaal阅读 3,577评论 5 99
  • 当你热切地期盼着你的第一份游戏行业的工作时。游戏公司会从你的简历和求职信来看你的潜力,而后通过面试来了解你。那么你...
    好怕怕阅读 9,023评论 0 14
  • 有时候,心里的苦泛出来,便成了泪。 有时候,眼里的泪流到心里。 回环, 回环。
    Dolphin_海豚阅读 172评论 0 1