Day12

一、EL表达式语言

1.1.EL表达式简介

lEL 全名为Expression LanguageEL主要作用:
(1)获取数据
•EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)
l使用EL表达式获取数据语法:“${标识符}”
lEL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从pagerequestsessionapplication四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。
l示例:${user}
 
lEL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
•${user.address.city}
•${user.list[0]}:访问有序集合某个位置的元素
•${map.key}  : 获得map集合中指定key的值
 
l结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,示例:
•迭代数组
•迭代collection类型集合
•迭代map类型集合
 
package cn.itcast.domain;

import java.util.Date;

public class Person {

    private String name = "aaa";
    private boolean sex;
    private int age;
    private Date birthday;
    private Address address;
    

    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isSex() {   //getSex()
        return sex;
    }

    public void setSex(boolean sex) {
        this.sex = sex;
    }
    
    
}

 

package cn.itcast.domain;

public class Address {
    private String city;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
    
    
}

 

 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="cn.itcast.domain.Person"%>
<%@page import="cn.itcast.domain.Address"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>el表达式获取数据</title>
  </head>
  
  <body>
    <br/>-----------------el表达式可以很方便获取各个域中的属性----------------------<br/>
    <% 
        request.setAttribute("data","xxx");
    %>
    ${data }   <!-- pageContext.findAttribute("data") -->
    
    
    <br/>-----------------el表达式可以很方便获取bean中的数据----------------------<br/>
    <% 
        Person p = new Person();
        p.setName("aaaaaaaaaaaaaaaaaa");
        request.setAttribute("person",p);
    %>   
    ${person.name }
    
    
    <br/>-----------------el表达式可以很方便获取bean中bean中。。。。。。。。中的属性----------------------<br/>
    <% 
        Person p1 = new Person();
        p1.setName("aaaaaaaaaaaaaaaaaa");
        Address address = new Address();
        address.setCity("北京");
        p1.setAddress(address);
        request.setAttribute("person",p1);
    %>   
    ${person.address.city }
    
    
    <br/>-----------------el表达式可以很方便获取Collection类型集合中的数据----------------------<br/>
     <% 
         List list = new ArrayList();
         list.add(new Person("aaa",12));
         list.add(new Person("bbb",13));
         list.add(new Person("ccc",14));
         
         request.setAttribute("list",list);
     %>
     ${list["1"].name }  ${list["1"].age }
     
     
    <br/>-----------------el表达式可以很方便获取map类型集合中的数据----------------------<br/> 
      <% 
         Map map = new HashMap();
         map.put("aa",new Person("aaa",12));
         map.put("bb",new Person("bbb",12));
         map.put("11",new Person("ccc",12));
         
         request.setAttribute("map",map);
     %>
     ${map.bb.name }
     ${map["11"].name }
     ${map[11].name }
     
  </body>
</html>

 

(2)执行运算:

利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}

EL表达式支持三种运算,简单的数字运算,逻辑运算,关系运算,除此之外还支持empty运算符,二元表达式以及[]和.运算符

语法:${运算表达式}EL表达式支持如下运算符:

(2.1)逻辑运算符

 

(2.2)关系运算符

(2.3)empty运算符:检查对象是否为null或“空”,很好用!!!

(2.4)二元表达式:${user!=null?user.name : “”} ,很好用!!!

(2.5)[ ] . 号运算符(用于取数据用的,一般用.,只有在.号运算符不行的时候用[],比如User.name,list["1"].name)

package cn.itcast.domain;

public class User {
    private String username;
    private String gender;
    private String likes[];

    
    
    public String[] getLikes() {
        return likes;
    }

    public void setLikes(String[] likes) {
        this.likes = likes;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    
    
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="cn.itcast.domain.User"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>el表达式执行运算</title>
  </head>
  
  <body>
      <!-- EL表达式中支持三种运算,简单的数字运算,逻辑运算,关系运算 -->
    ${1+1 }
    ${10*365*24*60 }
    ${user==null }
    ${username=="aaa" && password=="123" }
    
    
    
    <br/>-----------------empty运算符可以检测集合、数组是否为空或null--------------------------<br/>
    <% 
        List list = new ArrayList();
        request.setAttribute("list",list);
        
        List list1 = null;
        request.setAttribute("list1",list1);
    %>
    
    ${empty(list) }
    ${empty(list1) }
    
    
    <br/>-----------------二元运算符--------------------------<br/>
    <% 
        User user = new User();
        user.setUsername("aaa");
        session.setAttribute("user",user);
    %>
    ${user==null?'请先登陆 ':user.username }    <!-- EL表达式不能嵌套 -->
    
    
    <br/>-----------------二元运算符用作数据回显--------------------------<br/>
     <!-- 从数据库中取出原有数据显示在页面上的过程叫做数据回显 -->
    <% 
        user = new User();
        user.setGender("female");
        user.setUsername("aaa");
        request.setAttribute("user",user);
    %>
    <input type="radio" name="gender" value="male" ${user.gender=='male'?'checked':'' }><input type="radio" name="gender" value="female"  ${user.gender=='female'?'checked':'' }><br/>-----------------二元运算符用作数据回显--------------------------<br/>
     <!-- 从数据库中取出原有数据显示在页面上的过程叫做数据回显 -->
    
    <% 
        user = new User();
        user.setLikes(new String[]{"唱歌","足球"});
        request.setAttribute("user",user);
    %>
    
    <input type="checkbox" name="like" value="唱歌" checked>唱歌        <!-- 此处需要EL函数配合二元运算才能解决,学完EL函数之后就在解决这个问题  -->
    <input type="checkbox" name="like" value="跳舞">跳舞
    <input type="checkbox" name="like" value="蓝球">蓝球
    <input type="checkbox" name="like" value="足球" checked>足球
    
  </body>
</html>

 

 

 

(3)获取web开发常用对象

•EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
语法:${隐式对象名称:获得对象的引用
 
 
注意事项
•测试headerValues时,如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
•测试cookie时,例${cookie.key}取的是cookie对象,如访问cookie的名称和值,须${cookie.key.name}或${cookie.key.value}
 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>el隐式对象</title>
  </head>
  
  <body>
    
    ${pageContext.request.contextPath } <!--在EL表达式执行的时候首先判断这个标示符是不是11个隐式对象中的一个,如果是的话就将这个隐式对象传递给你-->
   <!-- ${request.contextPath }     这种写法是拿到的就不是pageContext中的request -->
    ${user }   <!-- pageContext.findAttribute("user") --> <!-- 以前经常这么说是有道理的 -->
    ${pageContext} <!-- 这里pageContext传递给你就表示将JSP种的8大隐式对象传递给你 -->
    
    <br/>----------------------<br/>
    <% 
        pageContext.setAttribute("aa","bb");  //map("aa","bb") pageContext中保存数据实际都存在pageScope的map中
    %>
    ${pageScope.aa }     <!-- pageScope代表page域中用于保存属性的Map对象 ,这个是从指定的page域中去找aa的值-->
      ${aa }                <!-- 这个是从四个域中去找aa的值 -->
      ${sessionScope.user!=null }        <!-- sessionScope代表session域中用于保存属性的Map对象,检测session域中的user就更加严谨了,从而避免其它域中的user干扰,这里可以用于判断用户是否登录 -->
      <!--
      requestScope 代表request域中用于保存属性的Map对象  
      applicationScope 代表application域中用于保存属性的Map对象,application域代表sevletContext
      -->
      
       <br/>----------param隐式对象,用于获取请求参数(数据回显)------------<br/>
       <!-- ${param} 用于保存请求参数的map集合,就是地址栏中的数据 ,这个超级好用,以前在注册表单失败了要做数据回显要用到javabean来存储表单数据,现在可以直接在这个隐式对象中取数据了,方便多了-->
     //http://localhost:8080/day12/3.jsp?name=aaa&name=bbb
       ${param.name }
       <!-- 
           paramValues表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个string[]
           这个隐式对象保存了多个请求参数
        -->
       ${paramValues.name[0] }
       ${paramValues.name[1] }
       
       <br/>----------用于获取请求头的el隐式对象------------<br/>
       <!-- header表示一个保存了所有http请求头字段的Map对象,请求头也保存在request-->
       ${header.Accept}    <!-- 获取Accept请求头 -->
       ${header["Accept-Language"] } <!-- 获取Accept-Language请求头时由于有的特殊符号-,说以要用[]获取 -->
       <!-- 
       headerValues,表示获取多个请求消息头,保存到数组中
       同上,返回string[]数组。注意:如果头里面有“-” ,例Accept-Encoding,则要headerValues[“Accept-Encoding”]
       
        -->
       
       <br/>----------用于获取cookie的el隐式对象------------<br/>
       <!-- cookie表示一个保存了所有cookie的Map对象 -->
       ${cookie}    <!-- 这是一个map -->
       ${cookie.JSESSIONID.name }      ${cookie.JSESSIONID.value }    <!-- 获取cookie中的JSESSIONID名称和值 -->
       
       <br/>----------用于获取web应用初始化参数的el隐式对象------------<br/>
       ${initParam.xxx } <!-- initParam用于保存sevletcontext里面用来保存初始化参数的 map集合 ,也就是保存web.xml文件中的数据-->
  </body>
</html>

 

(4)调用Java方法

•EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。
•示例:${prefix:method(params)}
•在EL表达式中调用的只能是Java类的静态方法。
•这个Java类的静态方法需要在TLD文件中描述,才可以被EL表达式调用。
•EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。
 
一般来说, EL自定义函数开发与应用包括以下三个步骤:
•编写一个Java类的静态方法
•编写标签库描述符(tld)文件,在tld文件中描述自定义函数。
•在JSP页面中导入和使用自定义函数
示例:开发对html标签进行转义的el function,以及二元运算的回显中用到的EL自定义函数
 
package cn.itcast.web.el;

import java.util.List;

public class ElUtils {
    
    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("&lt;");
                    break;
                case '>':
                    result.append("&gt;");
                    break;
                case '&':
                    result.append("&amp;");
                    break;
                case '"':
                    result.append("&quot;");
                    break;
                default:
                    result.append(content[i]);
                }
            }
            return (result.toString());
    }
    
    
    public static String join(String s1,String s2){
        return s1+s2;
    }
    
    public static double[] a(String s1,List list,int arr[],int j,Integer k){
        System.out.println("haha");
        return null;
    }
    
}
package cn.itcast.web.el;

import java.util.List;

public class ElUtils {
    
    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("&lt;");
                    break;
                case '>':
                    result.append("&gt;");
                    break;
                case '&':
                    result.append("&amp;");
                    break;
                case '"':
                    result.append("&quot;");
                    break;
                default:
                    result.append(content[i]);
                }
            }
            return (result.toString());
    }
    
    
    public static String join(String s1,String s2){
        return s1+s2;
    }
    
    public static double[] a(String s1,List list,int arr[],int j,Integer k){
        System.out.println("haha");
        return null;
    }
    
}

 

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>/itcast</uri>
    
    
    <function>
        <name>filter</name>
        <function-class>cn.itcast.web.el.ElUtils</function-class>
        <!-- 方法签名 -->
        <function-signature>java.lang.String filter( java.lang.String )</function-signature>
    </function>
    
     <function>
        <name>join</name>
        <function-class>cn.itcast.web.el.ElUtils</function-class>
        <!-- 方法签名 -->
        <function-signature>java.lang.String join( java.lang.String,java.lang.String )</function-signature>
    </function>
    
    <function>
        <name>a</name>
        <function-class>cn.itcast.web.el.ElUtils</function-class>
        <!-- 方法签名 --><!--EL函数比较复制的时候该如何去描述 -->
        <function-signature>double[] a(java.lang.String,java.util.List,int[],int,java.lang.Integer)</function-signature>
    </function>
    
</taglib>

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="cn.itcast.domain.User"%>
<%@taglib uri="/itcast" prefix="itcast" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>el函数</title>
  </head>
  
  <body>
      ${itcast:filter('<a href=""></a>') }
      <br/>
      <% 
          User user = new User();
          user.setUsername("小王");
          //session.setAttribute("user",user);
      %>
      ${user==null?'请先登陆':itcast:join('欢迎您:',user.username) }
      
      
      <br/>
      <%--EL函数比较复制的时候该如何去描述 --%>
      ${itcast:a("11",null,null,0,9) }
      
      <%--
      EL函数也可以移除JSP页面中的java代码,
      就相当于将java代码写在java中,用EL函数调用就可以 
      但是EL函数只能移除与web开发无关的代码,比如System.out.println("haha");
      但像request.getParameter("haha")这种与web开发有关的代码就不能移除,这种标签可以移动到自定义标签里面去
      因为服务器在调用自定义标签时会将pageContext传递进去
      --%>
  </body>
</html>

 

编写完标签库描述文件后,需要将它放置到<web应用>\WEB-INF目录中或WEB-INF目录下的除了classes和lib目录之外的任意子目录中。
TLD文件中的<uri> 元素用指定该TLD文件的URI,在JSP文件中需要通过这个URI来引入该标签库描述文件。
<function>元素用于描述一个EL自定义函数,其中:
•<name>子元素用于指定EL自定义函数的名称。
•<function-class>子元素用于指定完整的Java类名,
<function-signature>子元素用于指定Java类中的静态方法的签名,方法签名必须指明方法的返回值类型及各个参数的类型,各个参数之间用逗号分隔
EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。
注意:有些Tomcat服务器如不能使用EL表达式

  1)升级成tomcat6

  2)在JSP中加入<%@ page isELIgnored="false" %>

EL表达式保留关键字
所谓保留字的意思是指变量在命名时,应该避开下述的名字,以免程序编译时发生错误
 
 
 二、EL函数库(SUN公司写好的EL函数)
 
 1.JSTL中的常用EL函数
由于在JSP页面中显示数据时,经常需要对显示的字符串进行处理,SUN公司针对于一些常见处理定义了一套EL函数库供开发者使用。
所以在以后的开发中,在JSP页面中只要涉及到对字符串的处理有限考虑SUN公司的EL函数库
这些EL函数在JSTL开发包中进行描述,因此在JSP页面中使用SUN公司的EL函数库,需要导入JSTL开发包,并在页面中导入EL函数库,如下所示:
•在页面中使用JSTL定义的EL函数:

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

SUN公司定义的EL函数库的描述都在fn.tld里
 (1.1)fn:toLowerCase
fn:toLowerCase函数将一个字符串中包含的所有字符转换为小写形式,并返回转换后的字符串,它接收一个字符串类型的参数,例如
•fn:toLowerCase("Www.IT315.org") 的返回值为字符串“www.it315.org”
•fn:toLowerCase("")的返回值为空字符串
 
 (1.2)fn:toUpperCase
lfn:toUpperCase函数将一个字符串中包含的所有字符转换为大写形式,并返回转换后的字符串,它接收一个字符串类型的参数。例如:
•fn:toUpperCase("Www.IT315.org") 的返回值为字符串“WWW.IT315.ORG”
•fn:toUpperCase("")的返回值为空字符串
 
 (1.3)fn:trim
fn:trim函数删除一个字符串的首尾的空格,并返回删除空格后的结果字符串,它接收一个字符串类型的参数。需要注意的是,fn:trim函数不能删除字符串中间位置的空格。
•例如,fn:trim("   www.ysfox.com    ") 的返回值为字符串“www.ysfox.com”。
 
 (1.4)fn:length
 
fn:length函数返回一个集合或数组大小,或返回一个字符串中包含的字符的个数,返回值为int类型。fn:length函数接收一个参数,这个参数可以是<c:forEach>标签的items属性支持的任何类型,包括任意类型的数组、java.util.Collectionjava.util.Iteratorjava.util.Enumerationjava.util.Map等类的实例对象和字符串。
如果fn:length函数的参数为null或者是元素个数为0的集合或数组对象,则函数返回0;如果参数是空字符串,则函数返回0。 
 
 (1.5)fn:split
fn:split函数以指定字符串作为分隔符,将一个字符串分割成字符串数组并返回这个字符串数组。
fn:split函数接收两个字符串类型的参数,第一个参数表示要分割的字符串,第二个参数表示作为分隔符的字符串。
例如,fn:split("www.it315.org", ".")[1]的返回值为字符串“it315”
 
 
 (1.6)fn:join
fn:join函数以一个字符串作为分隔符,将一个字符串数组中的所有元素合并为一个字符串并返回合并后的结果字符串。fn:join函数接收两个参数,第一个参数是要操作的字符串数组,第二个参数是作为分隔符的字符串。
如果fn:join函数的第二个参数是空字符串,则fn:join函数的返回值直接将元素连接起来。例如:
•假设stringArray是保存在Web域中的一个属性,它表示一个值为{"www","it315","org"}的字符串数组,则fn:join(stringArray, “.")返回字符串“www.it315.org”
•fn:join(fn:split("www,it315,org", ","), ".") 的返回值为字符串“www.it315.org”
 
 (1.7)fn:indexOf  
 fn:indexOf函数返回指定字符串在一个字符串中第一次出现的索引值,返回值为int类型。fn:indexOf函数接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,那么,不管第二个参数字符串在第一个参数字符串中出现几次,fn:indexOf函数总是返回第一次出现的索引值;如果第一个参数中不包含第二个参数,则fn:indexOf函数返回-1。如果第二个参数为空字符串,则fn:indexOf函数总是返回0。例如:
lfn:indexOf("www.it315.org","t3") 的返回值为5
 
 (1.8)fn:contains
lfn:contains函数检测一个字符串中是否包含指定的字符串,返回值为布尔类型。fn:contains函数在比较两个字符串是否相等时是大小写敏感的。
lfn:contains函数接收两个字符串类型的参数,如果第一个参数字符串中包含第二个参数字符串,则fn:contains函数返回true,否则返回false。如果第二个参数的值为空字符串,则fn:contains函数总是返回true。实际上,fn:contains(string, substring)等价于fn:indexOf(string, substring) != -1
l忽略大小的EL函数:fn:containsIgnoreCase
 
(1.9)fn:startsWith
fn:startsWith函数用于检测一个字符串是否是以指定字符串开始的,返回值为布尔类型。
fn:startsWith函数接收两个字符串类型的参数,如果第一个参数字符串以第二个参数字符串开始,则函数返回true,否则函数返回false。如果第二个参数为空字符串,则fn:startsWith函数总是返回true。例如:
fn:startsWith("www.it315.org","it315")的返回值为false
与之对应的EL函数:fn:endsWith
 
(2.0)fn:replace
fn:replace函数将一个字符串中包含的指定子字符串替换为其它的指定字符串,并返回替换后的结果字符串。fn:replace方法接收三个字符串类型的参数,第一个参数表示要操作的源字符串,第二个参数表示源字符串中要被替换的子字符串,第三个参数表示要被替换成的字符串。例如:
fn:replace("www it315 org", " ", ".")的返回值为字符串“www.it315.org”
 
(2.1)fn:substring 
lfn:substring函数用于截取一个字符串的子字符串并返回截取到的子字符串。fn:substring函数接收三个参数,第一个参数是用于指定要操作的源字符串,第二个参数是用于指定截取子字符串开始的索引值,第三个参数是用于指定截取子字符串结束的索引值,第二个参数和第三个参数都是int类型,其值都从0开始。例如:
fn:substring("www.it315.org", 4, 9) 的返回值为字符串“it315”
 
(2,2)fn:substringAfter
fn:substringAfter函数用于截取并返回一个字符串中的指定子字符串第一次出现之后的子字符串。fn:substringAfter函数接收两个字符串类型的参数,第一个参数表示要操作的源字符串,第二个参数表示指定的子字符串,例如:
fn:substringAfter(“www.it315.org”, “.”)的返回值为字符串“it315.org”
与之对应的EL函数为:fn:substringBefore
 
(2.3)fn:escapeXml
用于转移HTML文件的,就是讲HTML的标签转移成源代码形式输出,这个转化比TomCat转化更彻底
 
最后还是那句话,在JSP中凡是涉及到处理字符串的首选SUN公司的EL函数库,就自己去查fn.tld,如果SUN公司的EL函数库找不到,就去找自定义标签库,如果自定义自定义标签库不行,就去自定义EL函数
 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="cn.itcast.domain.User"%>
<%@taglib uri="/itcast" prefix="itcast" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>el函数</title>
  </head>
  
  <body>
      ${itcast:filter('<a href=""></a>') }
      <br/>
      <% 
          User user = new User();
          user.setUsername("小王");
          //session.setAttribute("user",user);
      %>
      ${user==null?'请先登陆':itcast:join('欢迎您:',user.username) }
      
      
      <br/>
      <%--EL函数比较复制的时候该如何去描述 --%>
      ${itcast:a("11",null,null,0,9) }
      
      <%--
      EL函数也可以移除JSP页面中的java代码,
      就相当于将java代码写在java中,用EL函数调用就可以 
      但是EL函数只能移除与web开发无关的代码,比如System.out.println("haha");
      但像request.getParameter("haha")这种与web开发有关的代码就不能移除,这种标签可以移动到自定义标签里面去
      因为服务器在调用自定义标签时会将pageContext传递进去
      --%>
  </body>
</html>

 

 

三、JSTL标签库

l核心标签库
l国际化标签
l数据库标签
lXML标签
lJSTL函数(EL函数)
c.tld是核心标签库,fmt.tld是国际化标签库,sql.tld是数据库标签库,xml.tld是XML标签库,fn.tld是JSTL函数(EL函数),其它是其它版本的标签库。
我们已经学习了fn.tld,按照MVC核心思想,我们只学习核心标签库和国际化标签库,而数据库标签和XML标签库不学,这时因为在JSP页面只处理页面显示,没有必要处理数据库和XML,而国际化标签库需要学习国际化编程,将在之后学习到,所以我们现在只学习核心标签库c.tld
 
3.1核心标签库(jstl标签库)
(1)<c:out>标签
<c:out> 标签用于输出一段文本内容到pageContext对象当前保存的“out”对象中。
 

(2)<c:set>标签

<c:set>标签用于把某一个对象存在指定的域范围内,或者设置Web域中的java.util.Map类型的属性对象或JavaBean类型的属性对象的属性。 

 

 

(3)<c:remove>标签

<c:remove>标签用于删除各种Web域中的属性。

  其语法格式如下:

  <c:remove var="varName"  [scope="{page|request|session|application}"] /> 

 

(4)<c:catch>标签

<c:catch>标签用于捕获嵌套在标签体中的内容抛出的异常,其语法格式如下:<c:catch [var="varName"]>nested actions</c:catch>
var属性用于标识<c:catch>标签捕获的异常对象,它将保存在page这个Web域中。 
 
 
(4)<c:if>标签
<c:if test=“”>标签可以构造简单的“if-then”结构的条件表达式  (只要看见有var这个属性表示将某个var的值存到域中去)
 
 
 
(5)<c:choose>标签
<c:choose>标签用于指定多个条件选择的组合边界,它必须与<c:when><c:otherwise>标签一起使用。使用<c:choose><c:when><c:otherwise>三个标签,可以构造类似 “if-else if-else的复杂条件判断结构。
 
 
 
(6)<c:forEach>标签
<c:forEach>标签用于对一个集合对象中的元素进行循环迭代操作,或者按指定的次数重复迭代执行标签体中的内容。 

 

 

(7)<c:param>标签

JSP页面进行URL的相关操作时,经常要在URL地址后面附加一些参数。<c:param>标签可以嵌套在<c:import><c:url><c:redirect>标签内,为这些标签所使用的URL地址附加参数。
<c:param>标签在为一个URL地址附加参数时,将自动对参数值进行URL编码,例如,如果传递的参数值为“中国”,则将其转换为“%d6%d0%b9%fa”后再附加到URL地址后面,这也就是使用<c:param>标签的最大好处。
示例:<c:param name="name" value="value" />
 
(8)<c:url>标签

 <c:url>标签用于在JSP页面中构造一个URL地址,其主要目的是实现URL重写。URL重写就是将会话标识号以参数形式附加在URL地址后面

 

(9)<c:redirect>标签

l<c:redirect>标签用于实现请求重定向

 

(11)fortokens也是用来迭代的,主要迭代字符串

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="cn.itcast.domain.User"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

  <head>
    <title>jstl标签库</title>
  </head>
  
  <body>
    
    <br/>------------------c:out标签-------------------<br/>
    <c:out value="<a href=''></a>" escapeXml="true"/>    <!-- 转移HTML标签,将HTML标签源码输出 -->
    <c:out value="${user.username}" escapeXml="true" default="数据找不到"/>    <!-- 如果找不到用户名则会提示数据找不到 -->
   
 
     <br/>------------------c:set标签操作域-------------------<br/>
     <c:set var="data" value="xxxx" scope="application"></c:set> 
     ${data }
     
     
     <br/>------------------c:set标签操作map-------------------<br/>
     <% 
         Map map = new HashMap();
         request.setAttribute("map",map);
     %>
     <c:set property="data" value="yyyy" target="${map}"></c:set>
     ${map.data }
     
     <br/>------------------c:set标签操作 bean-------------------<br/>
     <% 
         User user = new User();
         request.setAttribute("user",user);
     %>
     <c:set property="username" value="uuuu" target="${user}"></c:set>
     ${requestScope.user.username }
     
    <br/>------------------c:if-------------------<br/>
    <c:if var="xx" test="${user11==null}" scope="page">
    </c:if>
    ${xx }    <!-- 结果为true,表示将test的值以xx名字存到page域中 -->
    
    <br/>------------------c:foreach  在页面产生数字,用于做分页-------------------<br/>
    <c:forEach var="i" begin="1" end="20">    <!-- 在JSTL中只要看见var属性,就表示将某个值存到域中,如果没有指定域则默认域就是pageContext域中 -->
        ${i }
    </c:forEach>
    
    <br/>------------------c:foreach  生成间色表格-------------------<br/>
     
     
    <% 
        map = new HashMap();
        map.put("aa","111");
        map.put("bb","222");
        map.put("cc","333");
        map.put("dd","444");
        map.put("ee","555");
        request.setAttribute("map",map);
    %>
    <style>
        .even{background-color:#FFCCFF }
        .odd{background-color:#FFCC66 }
        tr:hover{background-color:#FF6666}    <%-- 这个标签只有在xhtml的申明下才会有用,在html的申明下是无用的,xhtml的声明可以在TomCat的首页中的源码中找到--%>
    </style>
    <table border="1" width="200px">
        <c:forEach var="entry" items="${map}" varStatus="status">  <%--forEach在迭代数据的时候会把当前迭代的信息保存到对象中去,以关键字status存储到pageContext域中 --%>
            <tr class="${status.count%2==0?'even':'odd' }">  <%--status得到用于保存迭代信息的对象,然后它有一个属性count表示当前保存的是第几次迭代 --%>
                                            <%--上面这句代码的意思就是如果迭代的是偶数则给tr标签给一个class='even',如果迭代的是奇数的话九个tr标签给一个class='odd',这样就可以控制间色的问题了 --%>
                <td>${entry.key }</td>
                <td>${entry.value }</td>
            </tr>
        </c:forEach>
    </table>
    
    
    <br/>------------------c:url  重要!!!-------------------<br/>
    <c:url var="url" value="/servlet">
        <c:param name="name" value="中国"/>        <!-- 会自定编码,将汉字转化 -->
        <c:param name="password" value="123"/>    <!-- 为url附加参数 -->
    </c:url>
    <a href="${url }">点点</a>
    
    
    <br/>------------------fortokens标签也是用于迭代的,主要用于迭代字符串 -------------------<br/>
    
    <% 
        String s = "a,b,c,d,e";
        request.setAttribute("s",s);
    %>
    
    <c:forTokens var="ch" items="${s}" delims=",">
        ${ch }
    </c:forTokens>
  </body>
</html>

 

 四、JavaWEB开发-国际化

l软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
l国际化又称为 i18ninternationalization
 
l软件实现国际化,需具备哪些特征:
•对于程序中固定使用的文本元素,例如菜单栏、导航条等中使用的文本元素、或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不同语言的文本为之服务。
•对于程序动态产生的数据,例如(日期,货币等),软件应能根据当前所在的国家或地区的文化习惯进行显示。
 

 固定文本元素的国际化

l对于软件中的菜单栏、导航条、错误提示信息,状态信息等这些固定不变的文本信息,可以把它们写在一个properties文件中,并根据不同的国家编写不同的properties文件。这一组properties文件称之为一个资源包。
l在JavaAPI中提供了一个ResourceBundle 类用于描述一个资源包,并且 ResourceBundle类提供了相应的方法getBundle,这个方法可以根据来访者的国家地区自动获取与之对应的资源文件予以显示。
 
创建资源包和资源文件
l一个资源包中的每个资源文件都必须拥有共同的基名。除了基名,每个资源文件的名称中还必须有标识其本地信息的附加部分。例如:一个资源包的基名是“myproperties”,则与中文、英文环境相对应的资源文件名则为:
•“myproperites_zh.properties”  “myproperites_en.properties”
l每个资源包都应有一个默认资源文件,这个文件不带有标识本地信息的附加部分。若ResourceBundle对象在资源包中找不到与用户匹配的资源文件,它将选择该资源包中与用户最相近的资源文件,如果再找不到,则使用默认资源文件。例如:
•myproperites.properties
 
资源文件的书写格式
l资源文件的内容通常采用“关键字=值”的形式,软件根据关键字检索值显示在页面上。一个资源包中的所有资源文件的关键字必须相同,值则为相应国家的文字。
l并且资源文件中采用的是properties格式文件,所以文件中的所有字符都必须是ASCII字码,对于像中文这样的非ACSII字符,须先进行编码。(java提供了一个native2ascII命令用于编码)。例:

属性文件是不能保存中文的

 

native2asicii工具

mypreoperties_zh.properties

file=\u4E2D\u56FD
username=\u7528\u6237\u540D
password=\u5BC6\u7801
submit=\u63D0\u4EA4
currenttime=\u5F53\u524D\u65F6\u95F4


message=\u5728{0}\uFF0C\u4E00\u573A\u5267\u98CE\u6467\u6BC1\u4E86{1}\u6240\u623F\u5B50\uFF0C\u5BFC\u81F4\u4E86{2}\u7684\u635F\u5931\uFF01\uFF01

mypreoperties_en.properties

file=file
username=username
password=password
submit=submit
currenttime=Current Time

message=At {0, time, short} on {0, date}, a destroyed {1} houses and caused {2, number, currency} of damage.

mypreoperties.properties

file=file
username=username
password=password
submit=submit
currenttime=Current Time

message=At {0, time, short} on {0, date}, a destroyed {1} houses and caused {2, number, currency} of damage.

 

package cn.itcast.i18n;

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

public class Demo1 {

    public static void main(String[] args) {

        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.mypreoperties",Locale.ENGLISH);
        String value = bundle.getString("file");
        System.out.println(value);
    }

}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="java.text.DateFormat"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'login.jsp' starting page</title>
  </head>
  
  <body>
       <% 
        String language = request.getParameter("language");
        if(language==null){
            language = "zh";
        }
        Locale locale = new Locale(language);
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.mypreoperties",locale);
    %>
  
  
      <a href="login.jsp?language=zh">中文(网页)</a>
      <a href="login.jsp?language=en">english(pages)</a>
      
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      
      <%=bundle.getString("currenttime") %>:
      <% 
          Date date = new Date();
          DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM,locale);
          String result = df.format(date);
          out.write(result);
      %>
      
      <br/><br/><br/>
   
    <form action="">
        <%=bundle.getString("username") %><input type="text" name="username"><br/>
        <%=bundle.getString("password") %><input type="text" name="password"><br/>
        <input type="submit" value="<%=bundle.getString("submit") %>"><br/>
    </form>
    
  </body>
</html>

 

 

 动态数据的国际化

l数值,货币,时间,日期等数据由于可能在程序运行时动态产生,所以无法像文字一样简单地将它们从应用程序中分离出来,而是需要特殊处理。Java 中提供了解决这些问题的 API 类(位于 java.util 包和 java.text 包中)
lLocale 类
•Locale 实例对象代表一个特定的地理,政治、文化区域。
•一个 Locale 对象本身不会验证它代表的语言和国家地区信息是否正确,只是向本地敏感的类提供国家地区信息,与国际化相关的格式化和解析任务由本地敏感的类去完成。(若JDK中的某个类在运行时需要根据 Locale 对象来调整其功能,这个类就称为本地敏感类)

当然也可以用Local中的常量来构建一个local

 

DateFormat类(国际化日期)

lDateFormat类可以将一个日期/时间对象格式化为表示某个国家地区的日期/时间字符串。
lDateFormat 类除了可按国家地区格式化输出日期外,它还定义了一些用于描述日期/时间的显示模式的 int 型的常量,包括FULL, LONG, MEDIUM, DEFAULT, SHORT,实例化DateFormat对象时,可以使用这些常量,控制日期/时间的显示长度。
l例如,对于日期/时间“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”。

 

 实例化DateFormat类

l实例化DateFormat类有九种方式,以下三种为带参形式,下面列出的三种方式也可以分别不带参,或只带显示样式的参数。
•getDateInstance(int style, Locale aLocale):以指定的日期显示模式和本地信息来获得DateFormat实例对象,该实例对象不处理时间值部分。
•getTimeInstance(int style, Locale aLocale):以指定的时间显示模式和本地信息来获得DateFormat实例对象,该实例对象不处理日期值部分。
•getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):以单独指定的日期显示模式、时间显示模式和本地信息来获得DateFormat实例对象。

 

package cn.itcast.i18n;

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

public class Demo2 {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Date date = new Date();
        
        //输出date的日期部分
        DateFormat format = DateFormat.getDateInstance(DateFormat.FULL, Locale.KOREA);
        String result = format.format(date);
        System.out.println(result);
        
        //输出date的时间部分
        format = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.PRC);
        System.out.println(format.format(date));
        
        
        format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, Locale.CANADA);
        System.out.println(format.format(date));
        
    }

}

 

 

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

 

package cn.itcast.i18n;

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

public class Demo3 {

    /**把字符串解析成date对象
     * @param args
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {

        String s = "Wednesday, January 26, 2011 3:17 PM";
        DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT, Locale.CANADA);//注意,这里字符串中的日期时间是什么格式就必须用相应的格式,不然要报错
        Date date = format.parse(s);
        System.out.println(date);
    }

}

 

 

 

数字国际化:NumberFormat类

lNumberFormat 可以将一个数值格式化为符合某个国家地区习惯的数值字符串,也可以将符合某个国家地区习惯的数值字符串解析为对应的数值
lNumberFormat 类的方法:
•format 方法:将一个数值格式化为符合某个国家地区习惯的数值字符串
•parse 方法:将符合某个国家地区习惯的数值字符串解析为对应的数值。
 
l实例化NumberFormat类时,可以使用locale对象作为参数,也可以不使用,下面列出的是使用参数的。
lgetNumberInstance(Locale locale):以参数locale对象所标识的本地信息来获得具有多种用途的NumberFormat实例对象
lgetIntegerInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理整数的NumberFormat实例对象
lgetCurrencyInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理货币的NumberFormat实例对象
lgetPercentInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理百分比数值的NumberFormat实例对象

 

package cn.itcast.i18n;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

public class Demo4 {

    /**
     * 货币国际化
     * @param args
     * @throws ParseException 
     */
    public static void main(String[] args) throws ParseException {

        int price = 98;
        NumberFormat format = NumberFormat.getCurrencyInstance(Locale.CHINA);
        String result = format.format(price);
        System.out.println(result);
        
        String str = "¥98.00";
        int num = format.parse(str).intValue();
        System.out.println(num+1);
        
        
        double d = 0.5;
        format = NumberFormat.getPercentInstance();
        result = format.format(d);
        System.out.println(result);
    }

}

 

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="java.text.DateFormat"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'login.jsp' starting page</title>
  </head>
  
  <body>
       <% 
        String language = request.getParameter("language");
        if(language==null){
            language = "zh";
        }
        Locale locale = new Locale(language);
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.mypreoperties",locale);
    %>
  
  
      <a href="login.jsp?language=zh">中文(网页)</a>
      <a href="login.jsp?language=en">english(pages)</a>
      
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      
      <%=bundle.getString("currenttime") %>:
      <% 
          Date date = new Date();
          DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.MEDIUM,locale);
          String result = df.format(date);
          out.write(result);
      %>
      
      <br/><br/><br/>
   
    <form action="">
        <%=bundle.getString("username") %><input type="text" name="username"><br/>
        <%=bundle.getString("password") %><input type="text" name="password"><br/>
        <input type="submit" value="<%=bundle.getString("submit") %>"><br/>
    </form>
    
  </body>
</html>

 

动态文本国际化: MessageFormat(动态文本)

l如果一个字符串中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理。
l例如:

  At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage

•以上字符串中包含了时间、数字、货币等多个与国际化相关的数据,对于这种字符串,可以使用MessageFormat类对其国际化相关的数据进行批量处理。
l如果一个字符串中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理。
l例如:

  At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage

•以上字符串中包含了时间、数字、货币等多个与国际化相关的数据,对于这种字符串,可以使用MessageFormat类对其国际化相关的数据进行批量处理。也就是用占位符替换掉字符串中的敏感词
例如:

 

lAt 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and caused $1000000 of damage
l模式字符串:
      At {0} on {1},a destroyed {2} houses and caused {3} of damage  
 
l模式字符串:
•On {0}, a hurricance destroyed {1} houses and caused {2} of damage.
 
 
lMessageFormat类
•MessageFormat(String pattern,locale locale) 
•实例化MessageFormat对象,并装载相应的模式字符串。
•format(object obj[])
•格式化输出模式字符串,参数数组中指定占位符相应的替换对象。
•format(new Object[ ]{date, new Integer(99), new Double(1E7) })

 

 
package cn.itcast.i18n;

import java.text.MessageFormat;
import java.util.Date;
import java.util.Locale;

public class Demo5 {

    public static void main(String[] args) {

        String pattern = "On {0}, a hurricance destroyed {1} houses and caused {2} of damage.";
        
        MessageFormat format = new MessageFormat(pattern,Locale.CHINA);
        Object params[] = {new Date(),99,1000000};
        String result = format.format(params);
        System.out.println(result);
    }

}

 

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

import java.text.MessageFormat;
import java.util.Date;
import java.util.Locale;

public class Demo6 {

    public static void main(String[] args) {

        String pattern = "At {0, time, short} on {0, date}, a destroyed {1} houses and caused {2, number, currency} of damage.";
        MessageFormat format = new MessageFormat(pattern,Locale.US);
        Object arg[] = {new Date(),99,100000000};
        String result = format.format(arg);
        System.out.println(result);
    }
}

 

 

package cn.itcast.i18n;

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

public class Demo7 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.mypreoperties",Locale.US);
        String message = bundle.getString("message");
        
        MessageFormat mf = new MessageFormat(message,Locale.US);
        Object params[] = {new Date(),99,10000000};
        String result = mf.format(params);
        System.out.println(result);
    }

}

 

 

 
五、国际化标签
 
(1)<fmt:setLocale>标签用于创建一个Locale对象,然后存储到域中
 
 
 
 (2)<fmt:setBundle>标签用于创建一个Bundle
 
(3)<fmt:message>标签
 
 
(4)<fmt:bundle>标签
 
(6)<fmt:param>标签
 
(7)<fmt:requestEncoding>标签
 
(8)<fmt:timeZone>标签
 
(9)另外一个<fmt:setTimeZone>和<fmt:timeZone>一个是在标签体中有用,一个是在域中有用
 
(10)<fmt:formatDate>标签
 
 
<%@ 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>My JSP 'login.jsp' starting page</title>
  </head>
  
  <body>
    
     <% 
        String language = request.getParameter("language");
        if(language==null){
            language = "zh";
        }
        Locale locale = new Locale(language);
        ResourceBundle bundle = ResourceBundle.getBundle("cn.itcast.resource.mypreoperties",locale);
        request.setAttribute("locale",locale);
    %>
  
  
      <a href="login.jsp?language=zh">中文(网页)</a>
      <a href="login.jsp?language=en">english(pages)</a>
      
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
      
      
      
      <fmt:setBundle basename="cn.itcast.resource.mypreoperties" var="bundle"/>
      
      <fmt:message key="currenttime" bundle="${bundle}"/>:
      <fmt:setLocale value="${locale}"/>
      <fmt:formatDate value="<%=new Date() %>" dateStyle="long" timeStyle="short"/>
      
      <br/><br/><br/>
    
    
    <form action="">
        <fmt:message key="username" bundle="${bundle}"/><input type="text" name="username"><br/>
        <fmt:message key="password" bundle="${bundle}"/><input type="text" name="password"><br/>
        <input type="submit" value="<fmt:message key="submit" bundle="${bundle}"/>"><br/>
    </form>
    
  </body>
</html>

 

 

(11)<fmt:parseDate>标签

 

(12)<fmt:formatNumber>标签

 

(13)<fmt:parseNumber>标签

 

 

 六、log4j
lLog4j是apache开发的一套优秀的日志记录包,使用它可以很方便的输出程序运行信息。
l Log4j工作时基于一个配置文件,通过配置文件可以控制日志记录器:
•输出哪种类型的信息、
•输出到哪里
•输出采用什么格式
 
使用Log4j记录异常

1、在工程中导入log4j开发包,在classpath下添加log4j的配置文件:log4j.properties,获得日志记录器,输出程序信息。

l控制输出级别:level 是日志记录的优先级,分为OFFFATALERRORWARNINFODEBUGALL
lLog4j建议只使用四个级别,优先级从高到低分别是ERRORWARNINFODEBUG。通过在这里定义的级别,您可以控制程序中log.error()log.warn() log.info()log.debug() 等方法是否输出。
 
 
输出目的地
lAppender - 日志目的地,把格式化好的日志信息输出到指定的地方去 。
l配置语法:

  log4j.appender.appenderName = 目的地的完整类名

l其中,Log4j提供的appender有以下几种:
•org.apache.log4j.ConsoleAppender(控制台),
•org.apache.log4j.FileAppender(文件)
•org.apache.log4j.DailyRollingFileAppender(每天一个日志文件)
•org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
•org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
 
 
指定输出器输出格式
l设置语法
•log4j.appender.appenderName.layout=格式完整类名
lLog4j提供了如下几种layout:
•org.apache.log4j.SimpleLayout(包含级别和信息字符串)
•org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
•org.apache.log4j.HTMLLayout(以HTML表格形式布局)
•org.apache.log4j.PatternLayout(自定义布局模式)
 
#设置级别和目的地   
log4j.rootLogger=debug,appender1   
  
#输出到控制台   
log4j.appender.appender1=org.apache.log4j.ConsoleAppender  
 
#设置输出样式   
log4j.appender.appender1.layout=org.apache.log4j.PatternLayout   

#自定义样式     
log4j.appender.appender1.layout.ConversionPattern=%r [%t] [%p] - %c -%l -%m%n  
l参数:
l%p 输出优先级,即DEBUGINFOWARNERRORFATAL
l%r 输出自应用启动到输出该log信息耗费的毫秒数
l%c 输出所属的类目,通常就是所在类的全名
l%t 输出产生该日志事件的线程名
l%m 输出代码中指定的讯息,如log(message)中的message
l%n 输出一个回车换行符,Windows平台为“rnUnix平台为“n”
l%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM ddHH:mm:ss,SSS},输出类似:20021018221028921
l%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10) 
 
示例代码:
 
 
#设置记录级别:debug
log4j.rootLogger=info,appender1

#输出到控制台
log4j.appender.appender1=org.apache.log4j.ConsoleAppender
#样式为TTCCLayout   
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout

 

 

 

#设置日志记录器的输出级别、输出目的地
log4j.rootLogger=debug,appender1

#输出到文件(这里默认为追加方式)
log4j.appender.appender1=org.apache.log4j.FileAppender

#设置文件输出路径
log4j.appender.appender1.File=c:/Log4J.log

#设置输出样式
log4j.appender.appender1.layout=org.apache.log4j.TTCCLayout

 

 

 
#设置级别和目的地   
log4j.rootLogger=debug,appender1   
  
#输出到控制台   
log4j.appender.appender1=org.apache.log4j.ConsoleAppender  
 
#设置输出样式   
log4j.appender.appender1.layout=org.apache.log4j.PatternLayout   

#自定义样式     
log4j.appender.appender1.layout.ConversionPattern=%r [%t] [%p] - %c -%l -%m%n  

 

 
#设置级别和目的地   
log4j.rootLogger=debug,appender1,appender2   
  
#输出到控制台   
log4j.appender.appender1=org.apache.log4j.ConsoleAppender

#设置控制台输出样式   
log4j.appender.appender1.layout=org.apache.log4j.PatternLayout   

#自定义控制台输出样式   
log4j.appender.appender1.layout.ConversionPattern=[%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m%n  





#输出到文件(这里默认为追加方式)   
log4j.appender.appender2=org.apache.log4j.FileAppender

#设置文件输出路径     
log4j.appender.appender2.File=c:/Log4JDemo06.log   

#设置文件输出样式   
log4j.appender.appender2.layout=org.apache.log4j.PatternLayout   
log4j.appender.appender2.layout.ConversionPattern=[%d{HH:mm:ss:SSS}][%C-%M] -%m%n   

 

一.参数说明 


输出级别的种类 
ERROR、WARN、INFO、DEBUG 
ERROR 为严重错误 主要是程序的错误 
WARN 为一般警告,比如session丢失 
INFO 为一般要显示的信息,比如登录登出 
DEBUG 为程序的调试信息 


配置日志信息输出目的地 
log4j.appender.appenderName = fully.qualified.name.of.appender.class 
1.org.apache.log4j.ConsoleAppender(控制台) 
2.org.apache.log4j.FileAppender(文件) 
3.org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件) 
4.org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件) 
5.org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方) 


配置日志信息的格式 
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class 
1.org.apache.log4j.HTMLLayout(以HTML表格形式布局), 
2.org.apache.log4j.PatternLayout(可以灵活地指定布局模式), 
3.org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串), 
4.org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息) 


控制台选项 
Threshold=DEBUG:指定日志消息的输出最低层次。 
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。 
Target=System.err:默认情况下是:System.out,指定输出控制台 
FileAppender 选项 
Threshold=DEBUF:指定日志消息的输出最低层次。 
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。 
File=mylog.txt:指定消息输出到mylog.txt文件。 
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。 
RollingFileAppender 选项 
Threshold=DEBUG:指定日志消息的输出最低层次。 
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。 
File=mylog.txt:指定消息输出到mylog.txt文件。 
Append=false:默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容。 
MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件。

MaxBackupIndex=2:指定可以产生的滚动文件的最大数。 

 

日志信息格式中几个符号所代表的含义: 
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n 


-X号: X信息输出时左对齐; 
%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL, 
%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 
%r: 输出自应用启动到输出该log信息耗费的毫秒数 
%c: 输出日志信息所属的类目,通常就是所在类的全名 
%t: 输出产生该日志事件的线程名 
%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main (TestLog4.java:10) 
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。 
%%: 输出一个"%"字符 
%F: 输出日志消息产生时所在的文件名称 
%L: 输出代码中的行号 
%m: 输出代码中指定的消息,产生的日志具体信息 
%n: 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行 
可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如: 
1)%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。 
2)%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。 
3)%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。 
4)%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉。 

 


二.文件配置 

 

示例1 

log4j.rootLogger=DEBUG,A1,R 
#log4j.rootLogger=INFO,A1,R 
# ConsoleAppender 输出 
log4j.appender.A1=org.apache.log4j.ConsoleAppender 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n 
# File 输出 一天一个文件,输出路径可以定制,一般在根路径下 
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.R.File=blog_log.txt 
log4j.appender.R.MaxFileSize=500KB 
log4j.appender.R.MaxBackupIndex=10 
log4j.appender.R.layout=org.apache.log4j.PatternLayout 
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n

 

示例2 

下面给出的Log4J配置文件实现了输出到控制台,文件,回滚文件,发送日志邮件,输出到数据库日志表,自定义标签等全套功能。

 log4j.rootLogger=DEBUG,CONSOLE,A1,im 
#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE 
log4j.addivity.org.apache=true 
################### 
# Console Appender 
################### 
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.Threshold=DEBUG 
log4j.appender.CONSOLE.Target=System.out 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n 
##################### 
# File Appender 
##################### 
log4j.appender.FILE=org.apache.log4j.FileAppender 
log4j.appender.FILE.File=file.log 
log4j.appender.FILE.Append=false 
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
# Use this layout for LogFactor 5 analysis 
######################## 
# Rolling File 
######################## 
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender 
log4j.appender.ROLLING_FILE.Threshold=ERROR 
log4j.appender.ROLLING_FILE.File=rolling.log 
log4j.appender.ROLLING_FILE.Append=true 
log4j.appender.ROLLING_FILE.MaxFileSize=10KB 
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
#################### 
# Socket Appender 
#################### 
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender 
log4j.appender.SOCKET.RemoteHost=localhost 
log4j.appender.SOCKET.Port=5001 
log4j.appender.SOCKET.LocationInfo=true 
# Set up for Log Facter 5 
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout 
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n 
######################## 
# Log Factor 5 Appender 
######################## 
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender 
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000 
######################## 
# SMTP Appender 
####################### 
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender 
log4j.appender.MAIL.Threshold=FATAL 
log4j.appender.MAIL.BufferSize=10 
log4j.appender.MAIL.From=chenyl@yeqiangwei.com 
log4j.appender.MAIL.SMTPHost=mail.hollycrm.com 
log4j.appender.MAIL.Subject=Log4J Message 
log4j.appender.MAIL.To=chenyl@yeqiangwei.com 
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout 
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
######################## 
# JDBC Appender 
####################### 
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender 
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test 
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver 
log4j.appender.DATABASE.user=root 
log4j.appender.DATABASE.password= 
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n') 
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout 
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.A1.File=SampleMessages.log4j 
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j' 
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout 
################### 
#自定义Appender 
################### 
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender 
log4j.appender.im.host = mail.cybercorlin.net 
log4j.appender.im.username = username 
log4j.appender.im.password = password 
log4j.appender.im.recipient = corlin@yeqiangwei.com 
log4j.appender.im.layout=org.apache.log4j.PatternLayout 
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 

 

 
posted @ 2013-10-13 15:01  ysfox  阅读(295)  评论(0)    收藏  举报