自定义标签、JSTL(JSP Standard Tag Library)

1.自定义标签
[1]简介 html

在JSP2.0之后页面不推荐使用JSP脚本片断以及JSP表达式
使用EL来替换JSP表达式
使用标签来替换JSP脚本片断

jsp标签最终会被翻译完一段java代码,因此使用标签就是以标签的形式去调用Java代码
JSP内部已经为我们提供不少的预约义JSP动做标签,可是这些标签不能知足咱们的所有需求。
因此咱们须要开发自定义标签,多个自定义标签就构成了一个自定义标签库。java

[2]使用步骤
    1.建立一个标签处理器类
        > 标签处理器类须要实现SimpleTag接口。
        > SimpleTag接口中的方法:
            void doTag() --> 接口中最重要的方法,实际标签每次执行时都是调用doTag方法
            JspTag getParent() --> 获取当前标签的父标签,返回值是JspTag
            void setJspBody(JspFragment jspBody) --> 设置标签体的内容,这个方法由服务器调用,
                                                        服务器经过该方法将标签体传入处处理器类中,咱们本身不能调用,没有JspFragment.
            void setJspContext(JspContext pc) --> 设置当前页面的上下文,这个JspContext就是PageContext,能够用来获取页面中的其余隐含对象
            setParent(JspTag parent) --> 设置当前标签的父标签,服务器调用,服务器经过该方法,将父标签设置进处理器类

        > 一般咱们是经过继承SimpleTagSupport类来建立自定义标签。 *****
            - 经过该类建立自定义表签只须要根据需求重写doTag()方法。
            - 若是咱们想获取JspContext,直接调用getJspContext()
            - 若是想获取父标签,直接调用getParent()
            - 若是想获取标签体,直接调用getJspBody()

    2.编写一个tld文件(实际上就是一个xml文件)
        <tlib-version>1.0</tlib-version>
        <short-name>a</short-name>
        <uri>http://www.atguigu.com/taglib/a</uri>
            - 标签库的总体描述信息
            - tlib-version 声明标签库的版本
            - short-name 标签库前缀,在页面中经过前缀使用标签库
            - uri 标签库惟一约束,经过uri在页面中引入标签库(可选属性)

        <tag>
            <name>MyTag</name>
            <tag-class>com.atguigu.taglib.MyTag</tag-class>
            <body-content>empty</body-content>
        </tag>
            - tag标签是具体标签的描述信息,在一个tld文件中能够声明多个tag标签
            - name 标签的名字,在jsp中经过标签名来使用标签
            - tag-class 标签处理器类的全类名
            - body-content 标签体的类型,empty表明没有标签体(自结束标签)
                body-content有四个可选值:
                    经常使用
                    empty :表明当前标签没有标签体,是一个空标签(自结束标签)
                    scriptless:当标签体中的内容是一个EL表达式时,会有服务器自定解析

                    不经常使用
                    JSP : 表明当前标签体中能够是JSP的脚本片断,通常我们用的比较少
                    tagdependent:当标签体中内容是一个EL表达式时,服务器不会自动解析,不用

                结论:
                    若是标签没有标签体则使用empty
                    若是有标签体则使用scriptless
        当标签中具备属性时,还须要在tag标签中添加一个attribute标签
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
            - name 表示属性的名字
            - required 属性是否为必须的
            - rtexprvalue 是否自动解析EL表达式

    3.在JSP中使用自定义标签
        > 经过taglib指令向页面中导入自定义标签库
            - <%@ taglib prefix="a" uri="http://www.atguigu.com/taglib/a" %>

2.JSTL(JSP Standard Tag Library)
[1] JSTL简介web

JSTL是JSP的标准标签库
JSTL为咱们提供了一些经常使用的标签,供咱们平常开发使用(if 、 if…else 、遍历 、 日期格式化)
标签库
- core :核心标签库
- 最经常使用的一个标签库,也就是咱们熟悉c标签。sql

- fn :函数标签库
            - 函数标签库它须要结合EL表达式使用,主要定义了一些字符串操做的方法。

        - fmt :格式化标签库
            - 主要用来作日期、数字的格式化以及国际化
            - 20151019 2015/10/19  10/19/2015
            - 10000 10,000

        - sql : 数据库标签库  
            - 主要用来在JSP中操做数据库的,已淘汰

        - xml : xml标签库  
            - 主要用来在JSP操做解析XML文档,已淘汰

    > JSTL的使用
        使用JSTL须要先导入两个jar包
            taglibs-standard-impl-1.2.1.jar
            taglibs-standard-spec-1.2.1.jar

[2] 核心标签库   
     - 导入核心标签库
        <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     - 核心标签库通常使用c做为前缀,因此咱们也称核心标签库为c标签。
     - c标签是咱们JSTL中最经常使用的一个标签库,它里边封装了不少开发中经常使用的功能。

     c:out
     做用:向页面中输入一个内容
     例子:<c:out value="" default="" escapeXml=""></c:out>
     属性:
        value : 要输出内容
        default : 当内容为空时显示的默认值
        escapeXml : 是否自动转义特殊字符,默认值为true 自动转义,通常不修改该属性

    c:set
    做用:向域中设置一个属性
    例子:<c:set var="name" value="孙悟空" scope="request"></c:set>
    属性:
        var :向域中存储的属性名
        value :向域中存储的属性值
        scope :向那个域中添加属性,四个可选值(page request session application),默认是page

    c:remove
    做用:移除域中的一个属性
    例子:<c:remove var="name" scope="session"/>
    属性:
        var :要移除的属性的名字
        scope :要移除的属性所在的域,四个可选值(page request session application)
            若是不设置该属性,则默认移除四个域中指定属性。

    c:if
    做用 :至关于java中if语句
    例子: 
        <c:if test="${empty param.name }">
            <h3>您没有输入name属性!</h3>
        </c:if>
    属性:
        test :接收一个boolean类型的值
            若是test的值为true则标签体执行
            不然不执行标签体

    c:choose c:when c:otherwise
    做用:至关于if...else
    例子:
            <c:choose>
                <c:when test="${param.score == 100 }">
                    <h3>恭喜您考了100分!</h3>
                </c:when>
                <c:otherwise>
                    <h3>恭喜你,你不及格!</h3>
                </c:otherwise>
            </c:choose>
    属性:
        when标签中的test属性:
            接收一个boolean类型的值
                若是test的值为true则标签体执行
                    不然不执行标签体

    注意:在choose标签中能够指定多个when标签,可是只有一个when会执行。
            当全部的when标签都不执行时,则otherwise标签执行。

        c:when和c:otherwise不能脱离c:choose使用。


    c:forEach
    做用:能够在页面中对集合进行遍历
    例子:
        <c:forEach items="${list}" var="hero">
            ${hero} <br />
        </c:forEach>

        <c:forEach items="${map }" var="user">
            ${user.key} --- ${user.value} <br />
        </c:forEach>
    属性:
        items:要遍历的集合
        var:对集合中的对象引用的名字

    注意:在遍历Map时,返回的是一组一组的键值对结构
        咱们能够经过对象.key获取键,经过对象.value获取值

    做用:能够用来遍历一组数
    例子:
        <c:forEach begin="1" end="20" var="index" step="1">
            <a href=#>${index}</a>
        </c:forEach>
    属性:
        begin :开始的位置,注意begin不能小于0
        end :结束的位置
        var :引用的名字
        step :步长,每次自增的大小

    c:url
    做用:能够建立一个完整的绝对路径
    例子:
        <c:url value="/index.jsp">
            <c:param name="name" value="孙悟空"></c:param>
            <c:param name="age" value="18"></c:param>
        </c:url>
    属性:
        value:要设置的地址,注意该地址要以/开头,不然不会加上项目名
    在url标签中能够添加c:param标签,能够自动为地址拼接上请求参数。

    c:redirect
    做用:请求的重定向
    例子:
        <c:redirect url="/index.jsp">
            <c:param name="name" value="唐僧"></c:param>
        </c:redirect>
    属性:
        url:
            重定向到目标地址,注意该地址不要本身添加项目名。
        在redirect标签中能够添加c:param标签,能够自动为地址拼接上请求参数。

    设置绝对路径的三种方式:
        1.<c:set var="ctx" value="${pageContext.request.contextPath }"></c:set>
            使用这种方式,能够经过${ctx}在页面中代替项目名

        2.使用<c:url value="/index.jsp"></c:url>
            使用url标签,它会自动为绝对路径加上项目名

        3.<base href="http://${pageContext.request.serverName }:${pageContext.request.serverPort }${pageContext.request.contextPath }/" />
            使用base标签能够为页面中全部的相对路径,加上项目名 

[3] 函数标签库   
        做用:函数标签库须要配合EL表达式使用,它里面的方法都是一些字符串的操做
        引入函数标签库:<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

        例子:

            ${fn:contains("hello","He") } <br /> 判断前一个字符串是否包含后一个字符串

            ${fn:containsIgnoreCase("hello","He") } <br /> 判断前一个字符串是否包含后一个字符串,不区分大小写

            ${fn:endsWith("hello","alo") }<br /> 判断前一个字符串是否之后一个字符串结尾

            <!-- 自动将特殊字符转义 -->
            ${fn:escapeXml("<html></html>") }<br /> 自动将特殊字符进行转义

            <!-- fn:join用于将一个String数组转换一个字符串,第二个参数表明的链接符 -->
            ${fn:join(strs,",") }<br /> 将一个String数组,以指定字符串拼接为一个新的字符串

            ${fn:split("a,b,c,d,e",",")[2] }<br /> 将一个字符串,以指定字符拆分为一个字符数组

            ${fn:trim("      abcd       ") }<br /> 去掉字符串的先后空格

            剩下方法参照 alt+/

[4] 练习

==========================数据库

/**

JSTL
JSTL简介
   JSP虽然为咱们提供了EL表达式用来替代JSP表达式,可是因为EL表达式仅仅具备输出功能,而不替代页面中的JSP脚本片断。
   为了解决这个问题,JSP为咱们提供了能够自定义标签库(Tag Library)的功能。
   所谓自定义标签库就是指能够在JSP页面中以相似于HTML标签的形式调用Java中的方法。使用方法和咱们JSP动做标签相似。
   而为了方便开发使用Sun公司又定义了一套通用的标签库名为JSTL(JSP Tag Standard Tag Library),里面定义不少咱们开发中经常使用的方法,方便咱们使用。
   JSTL的标准由Sun公司定制,Apache的Jakarta小组负责实现。
   JSTL由5个不一样功能的标签库组成。
使用JSTL
   使用JSTL必须在项目中导入两个jar包
   taglibs-standard-impl-1.2.1.jar
   taglibs-standard-spec-1.2.5.jar
   而后还须要在JSP页面中经过taglib标签引入标签库。
   <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
   prefix用来指定前缀名,咱们经过该名来使用JSTL
   uri至关于库的惟一标识,由于JSTL由多个不一样的库组成,使用该属性指定要导入哪一个库。
   使用JSTL
   <c:out value="hello"></c:out>
   这个例子标识,调用前缀为c的标签的out方法,向页面中输出value属性中的字符串。
   JSTL的使用很是像html标签。
标签库
   JSTL由五个不一样功能的标签库组成。
功能范围    URI 前缀
核心  http://java.sun.com/jsp/jstl/core   c
格式化 http://java.sun.com/jsp/jstl/fmt    fmt
函数  http://java.sun.com/jsp/jstl/functions  fn
数据库(不使用)    http://java.sun.com/jsp/jstl/sql    sql
XML(不使用)    http://java.sun.com/jsp/jstl/xml    x

核心标签(Core Tags)
   Core标签库,包括了咱们最经常使用的标签。
   要使用Core标签库须要在JSP页面中加入:
   <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out>
   <c:out>用于计算一个表达式并将结果输出到当前页面。
   功能相似于JSP表达式<%= >和EL表达式${}
   能够设置的属性
   value
   做用:要输出的值
   参数类型:Object
   default
   做用:当value为null时显示的默认值。
   参数类型:Object
   
   escaXml
   做用:是否对特殊字符进行转义。
   参数类型:boolean
   例:
   <c:out value="${user.name}" default="" escapeXml="true"></c:out>
<c:set>
   <c:set>用于添加或修改域中的属性
   能够设置的属性:
   value
   做用:要设置的值
   参数类型:Object
   var
   做用:表示域中存放的属性名。
   参数类型:String
   scope
   做用:指定域(pageContext、request、session、application),若不指定则为pageContext
   参数类型:String
   target
   做用:要修改的域对象的属性名(必须是JavaBean或者Map)
   参数类型:Object
   property
   做用:指定要修改的对象的属性名
   参数类型:String
   例
   设置属性:
   <c:set var="key" value="value" scope="request"></c:set>
   修改属性:
   <c:set property="name" target="${user}" value="孙悟空"></c:set>
<c:remove>
   <c:remove>用于移除域中的属性
   能够设置的属性:
   var
   做用:设置要移除的属性的名字
   做用:String
   scope
   做用:设置要移除属性所在的域,若不指定则删除全部域中的对应属性
   参数类型:String
   例:
   移除全部域中key属性:<c:remove var="key"/>
   移除request中的key属性: <c:remove var="key" scope="request"/>
<c:if>
   <c:if>用于实现if语句的判断功能
   可设置的属性
   test
   做用:设置if判断的条件,用于判断标签体是否被执行
   参数类型:boolean
   var
   做用:用于指定接收判断结果的变量名
   参数类型:boolean
   scope
   做用:指定判断结果保存到哪一个域
   参数类型:String
   例:
<c:if test="${empty user }" var="isUserEmpty" scope="request">
        用户为空
    </c:if>
<c:choose>、<c:when>、<c:otherwise>
   <c:choose>、<c:when>、<c:otherwise>三个标签配合使用,功能相似于Java中的if/else
   <c:choose>是<c:when>和<c:otherwise>的父标签
   <c:when>的属性
   test
   做用:用于设置判断条件,若正确则c:when中的代码执行,不然不执行
   参数类型:boolean
   <c:otherwise>
   做用:若是全部的<c:when>都没有执行则执行<c:otherwise>的标签体
   例:
<c:choose>
        <c:when test="${param.age>=18 }">
            您已经成年
        </c:when>
        <c:otherwise>
            您未成年
        </c:otherwise>
    </c:choose>
<c:forEach>
   <c:forEach>用于对多个对象的集合进行迭代,重复执行标签体,或者重复迭代固定的次数。
   可设置属性:
   var
   做用:设置遍历出对象的名称
   参数类型:String
   items
   做用:指定要遍历的集合对象
   参数类型:数组、字符串和各类集合
   varStatus
   做用:指定保存迭代状态的对象的名字,该变量引用的是一个LoopTagStatus类型的对象,经过该对象能够得到一些遍历的状态:
   count
   index
   first
   last
   name
   参数类型:String
   begin
   做用:指定遍历的开始位置
   参数类型:int
   end
   做用:指定遍历的结束位置
   参数类型:int
   step
   做用:迭代的步长
   参数类型:int
   例:
<c:forEach items="${list}" var="user" begin="0" end="4" step="2" varStatus="vs">
        ${vs.index} -- ${user.name } -- ${user.age }<br />
    </c:forEach>
<c:url>
   <c:url>主要用来重写URL地址
   可设置的属性:
   value
   做用:设置要处理的URI地址,注意这里要以/开头
   可接受参数:String
   var
   做用:修改后存储到域对象中的uri属性名。
   可接受参数:String
   scope
   做用:设置修改后uri存放的域
   可接受参数:String
   例:
   使用相对路径:
<c:url value="index.jsp" var="uri" scope="request">
    <c:param name="name" value="张三"></c:param>
</c:url>
   会生成以下地址:index.jsp?name=%E5%BC%A0%E4%B8%89
   使用绝对路径会自动在路径前加上项目名:
<c:url value="/index.jsp" var="uri" scope="request">
    <c:param name="name" value="张三"></c:param>
</c:url>
   会生成以下地址:/Test_JSTL/index.jsp?name=%E5%BC%A0%E4%B8%89
<c:redirect>
   <c:redirect>主要用于将请求重定向到另外一个资源地址
   可设置的属性:
   uri
   做用:指定要重定向到的目标地址,注意这里指定绝对路径会自动加上项目名
   参数类型:String
   例:
<c:redirect url="/target.jsp"></c:redirect>
JSTL函数(JSTL Functions)
   函数标签库是在JSTL中定义的标准的EL函数集。
   函数标签库中定义的函数基本上都是对字符串的操做。
   引入:<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
fn:contains和fn:containsIgnoreCase
做用:用于判断字符串中是否包含指定字符串,containsIgnoreCase忽略大小写。
语法:fn:contains(string,subString)  boolean
参数和返回值:
参数  类型  做用
string  String  源字符串
subString   String  要查找的字符串
返回值 boolean 若string中包含subString则返回true,不然返回false
例:
    ${fn:contains("hello","HE")}false
    ${fn:containsIgnoreCase("hello","HE")}true
fn:startsWith和fn:endsWith
做用:判断一个字符串是否以指定字符开头(startsWith)或结尾(endsWith)
语法:fn:startsWith(string , prefix)  boolean
      fn:endsWith(string,suffix)  boolean
参数和返回值:
参数  类型  做用
string  String  源字符串
prefix 或 suffix String  要查找的前缀或后缀字符串
返回值 boolean 符合要求返回true,不然返回false
例:${fn:startsWith("hello","he") }true
    ${fn:endsWith("hello","he") }false
fn:indexOf
做用:在一个字符串中查找指定字符串,并返回第一个符合的字符串的第一个字符的索引。
语法:fn:indexOf(string,subString)  int
参数和返回值:
参数  类型  做用
string  String  源字符串
subString   String  要查找的字符串
返回值 int 若在string中找到subString则返回第一个符合的索引,若没有符合的则返回-1
例:${fn:indexOf("hello",'e') }1
fn:replace
做用:将一个字符串替换为另一个字符串,并返回替换结果
语法:fn:replace(str , beforeSubString , afterSubString)  String
参数和返回值:
参数  类型  做用
str String  源字符串
beforeSubString String  被替换的字符串
afterSubString  String  要替换的新字符串
返回值 String  替换后的字符串
例:${fn:replace("hello","llo",'e') }  hee
fn:substring
做用:截取字符串
语法:fn: substring (str , beginIndex , endIndex)  String
参数和返回值:
参数  类型  做用
str String  源字符串
beginIndex  int 开始位置索引(包含该位置)
endIndex    int 结束位置索引(不包含自身)
返回值 String  返回截取的字符串
例:${fn:substring("hello",1,3) }  el
fn:substringBefore和fn:substringAfter
做用:返回一个字符串指定子串以前(substringBefore)以后(substringAfter)的字符串
语法:fn: substringBefore(string,subString)  String
fn: substringAfter (string,subString)  String
参数和返回值:
参数  类型  做用
str String  源字符串
subString   int 指定str中的一个子串,该串以前或以后的字符串将被返回。
返回值 String  返回截取的字符串
例:${fn:substringBefore("hello","l") }  he
    ${fn:substringAfter("hello","l") }  lo
fn:split
做用:将一个字符串拆分红字符串数组。
语法:fn:split(string,delimiters)  String
参数和返回值:
参数  类型  做用
str String  要被拆分的字符串
delimiters  String  指定根据什么内容拆分字符串
返回值 String[]    返回拆分后的字符串数组
例:${fn:split("a-b-c-d-e-f-g","-")}  返回一个数组对象[a,b,c,d,e,f,g]
fn:join
做用:将数组中全部元素链接成一个字符串
语法:fn:join(array,sparator)  String
参数和返回值:
参数  类型  做用
str String  要被拆分的字符串
sparator    String  在结果中每一个元素之间的分隔符
返回值 String[]    拼接以后的结果
例:
<%
String[] strs = new String[]{"a","b","c","d","e","f"};
pageContext.setAttribute("strs", strs);
%>
${fn:join(strs,'-') }
    返回:a-b-c-d-e-f
fn:toLowerCase和fn:toUpperCase
做用:将字符串都转换成大写(toUpperCase)或小写(toLowerCase)字符
语法:
    fn: toLowerCase (str)  String
fn: toUpperCase(str)  String
参数和返回值:
参数  类型  做用
str String  源字符串
返回值 String  转换为大写或小写的字符串

例:${fn:toLowerCase("ABCDEFG") }  abcdefg
    ${fn:toUpperCase("abcdefg") }  ABCDEFG
fn:trim
做用:去掉字符串的先后空格
用法:fn:trim(str)  String
参数和返回值:
参数  类型  做用
str String  源字符串
返回值 String  去掉先后空格的结果
例:${fn:trim(" hello ") }  hello
fn:length
做用:返回集合或者字符串的长度
用法:fn:trim(input)  int
参数和返回值:
参数  类型  做用
input   String、集合、数组    要计算长度的目标
返回值 int 集合或字符串的长度
例:${fn:length("hello") }5



















*/