自定义标签简介

1 自定义标签简介

    •自定义标签主要用于移除Jsp页面中的<%java%>代码。

    •快速入门:使用自定义标签输出客户机IP

    •移除jsp页面中的java代码,只需要完成两个步骤:

    •实现SimpleTag接口/SimpleTagSupport类,重写doTag()方法。

    •编写标签库描述符(tld)文件,在tld文件中对自定义标签进行描述,并放置在WEB-INF/目录下。

    •完成以上操作,即可在JSP页面中导入和使用自定义标签。

    •查看SimpleTag接口api文档,分析自定义标签的执行流程。

    SUN公司为降低标签技术的学习难度,在JSP 2.X中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:

    •setJspContext方法

    •setParent和getParent方法

    •setJspBody方法

    •doTag方法

    setJspContext方法:用于把JSP页面的pageContext对象传递给标签处理器对象

    setParent方法:用于把父标签处理器对象传递给当前标签处理器对象

    getParent方法:用于获得当前标签的父标签处理器对象

    setJspBody方法:用于把代表标签体的JspFragment对象(即标签体内容)传递给标签处理器对象

    doTag方法:用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容。

    SimpleTag接口方法的执行顺序

    当web容器开始执行标签时,会调用如下方法完成标签的初始化

        •WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。

        •WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。

        •如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。

        •如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。

    执行标签时:

        •容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

    JspFragment类

    javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的,它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,这段JSP片段中不能包含JSP脚本元素,即<%%>。

    WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:getJspContext方法

    •用于返回代表调用页面的JspContext对象.

    •public abstract void invoke(java.io.Writer out)

    •用于执行JspFragment对象所代表的JSP代码片段

    •参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)

    invoke方法详解

    JspFragment.invoke方法可以说是JspFragment最重要的方法,利用这个方法可以控制是否执行和输出标签体的内容、是否迭代执行标签体的内容或对标签体的执行结果进行修改后再输出。例如:

    •在标签处理器中如果没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容;

    •在标签处理器中重复调用JspFragment.invoke方法,则标签体内容将会被重复执行;

    •若想在标签处理器中修改标签体内容,只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。

    开发带属性的标签

    自定义标签可以定义一个或多个属性,这样,在JSP页面中应用自定义标签时就可以设置这些属性的值,通过这些属性为标签处理器传递参数信息,从而提高标签的灵活性和复用性。

    要想让一个自定义标签具有属性,通常需要完成两个任务:

        •在标签处理器中编写每个属性对应的setter方法

        •在TLD文件中描术标签的属性

    为自定义标签定义属性时,每个属性都必须按照JavaBean的属性命名方式,在标签处理器中定义属性名对应的setter方法,用来接收JSP页面调用自定义标签时传递进来的属性值。例如属性url,在标签处理器类中就要定义相应的setUrl(String url)方法。

    在标签处理器中定义相应的set方法后,JSP引擎在解析执行开始标签前,会调用setter属性方法,为标签设置属性。

元素名

是否必须指定

描 述

description

用于指定属性的描述信息。

name

用于指定属性的名称。属性名称是大小写敏感的,并且不能以jsp、_jsp、java和sun开头。

required

用于指定在JSP页面中调用自定义标签时是否必须设置这个属性。其取值包括true和false,默认值为false,true表示必须设置,否则可以设置也可以不设置该属性。

rtexprvalue

rtexprvalue是runtime expression value(运行时表达式)的英文简写,用于指定属性值是一个静态值或动态值。其取值包括true和false,默认值为false,false表示只能为该属性指定静态文本值,例如"123";true表示可以为该属性指定一个JSP动态元素,动态元素的结果作为属性值,例如JSP表达式<%=value %>。

type

用于指定属性值的Java类型。

2 为什么需要使用自定义标签

  1)与JSP页面整体统一
  2)还具有一定的业务逻辑功能,例如:循环,判段。。。
  3)替代原JSP页面中<%%>

3 如何创建自定义标签

  a写一个标签处理类
//标签处理类

public class IpTag implements SimpleTag {
    private PageContext pageContext;
    //Web容器调用NO1
    public void setJspContext(JspContext pc) {
        System.out.println("setJspContext()");
        pageContext = (PageContext) pc;
    }
    //Web容器调用NO2
    public void doTag() throws JspException, IOException {
        System.out.println("doTag()");
        //取得HttpServletRequest请求对象
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        //取得客户端的IP地址
        String ip = request.getRemoteAddr();
        //取得out(JspWriter)对象
        JspWriter out = pageContext.getOut();
        //向浏览器输出
        out.write("<font size='44' color='red'>"+ip+"</font>");
    }
        ...
}

  b在/WEB-INF/目录下,写一个*.tld文件,目的是让Web容器知道自定义标签和标签处理类的对应关系

<?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">
  <tlib-version>1.0</tlib-version>
  <short-name>simple</short-name>
  <uri>http://java.sun.com/jsp/jstl/simple</uri>
  <tag>
    <name>ip</name>
    <tag-class>cn.itcast.web.jsp.tag.IpTag</tag-class>
    <body-content>empty</body-content>
  </tag>
</taglib>

  c在JSP页面中,通过<%@taglib%>指令引用标签库

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/simple" prefix="simple" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
      客户端IP为:<simple:ip/>
  </body>
</html>

  d部署web应用,访问simple.jsp即可

4 标签处理过程
  1)SimpleTag接口中有5个方法,这5个方法容器会在适当的时候先用调用,其中doTag()方法最为核心,该方法中封装了
    该标签的处理业务逻辑
  2)项目中通常都会使用SimpleTagSupport这个类,该类已经对SimpleTag接口实现
 
*5 标签的应用
  1)执行标签体:jspFragment.invoke(null); 
  2)不执行标签体:不让其执行//jspFragment.invoke(null);
  3)不执行标签体后的内容:抛SkipPageExcetion()
  4)重复执行标签体的内容:以属性的方式注入
  5)改变标签中的内容变化:先将标签体的内容输出到缓存中,例如:StringWriter中
  6)当某些标签是排它执行,此时可以在这些标签外嵌入父标签,在父标签中做一个标志位,来表示是还执过
  7)当在JSP页面中,有相同的代码时,可以将其封装成自定义标签

package cn.itcast.web.jsp.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:for1>标签处理类
public class For1Tag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        for(int i=1;i<=10;i++){
            this.getJspBody().invoke(null);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:for2 count="10">标签处理类
public class For2Tag extends SimpleTagSupport {
    private int count;
    //WEB容器调用NO1
    public void setCount(int count) {
        this.count = count;
        System.out.println("setCount()");
    }
    //WEB容器调用NO2
    public void doTag() throws JspException, IOException {
        for(int i=1;i<=this.count;i++){
            this.getJspBody().invoke(null);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:for3 var="num" begin="1" end="10" step="1(默认为1)">标签处理类
public class For3Tag extends SimpleTagSupport {
    private String var;
    private int begin;
    private int end;
    private int step = 1;
    public void setVar(String var) {
        this.var = var;
    }
    public void setBegin(int begin) {
        this.begin = begin;
    }
    public void setEnd(int end) {
        this.end = end;
    }
    public void setStep(int step) {
        this.step = step;
    }
    public void doTag() throws JspException, IOException {
        for (int i = this.begin; i <= this.end; i += this.step) {
            PageContext pageContext = (PageContext) this.getJspContext();
            pageContext.setAttribute(this.var,i);
            this.getJspBody().invoke(null);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:forEach var="s" items="${LIST/SET}">标签处理类
//<simple:forEach var="s" items="${MAP}">标签处理类
public class ForeachTag extends SimpleTagSupport {
    private String var;
    private Object items;
    /*
     * 将Map类型转成Collection类型
     */
    private Collection collection;
    
    public void setVar(String var) {
        this.var = var;
    }
    public void setItems(Object items) {
        this.items = items;
        if(this.items instanceof Collection){
            this.collection = (Collection) items;
        }else if(this.items instanceof Map){
            Map map = (Map) items;
            this.collection = map.entrySet(); 
        }
    }
    public void doTag() throws JspException, IOException {
        //NO1迭代集合
        Iterator<Object> it = this.collection.iterator();
        while(it.hasNext()){
            //NO2将集合中的每一个元素取出来,绑定到PageContext域对象
            Object obj = it.next();
            PageContext pageContext = (PageContext) this.getJspContext();
            pageContext.setAttribute(this.var,obj);
            //NO3执行标签体
            this.getJspBody().invoke(null);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
    
//<simple:if test="${10<5}">标签处理类
public class IfTag extends SimpleTagSupport {
    private boolean test;
    public void setTest(boolean test) {
        this.test = test;
    }
    public void doTag() throws JspException, IOException {
        if(test){
            //执行标签体
            this.getJspBody().invoke(null);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;

//标签处理类
public class IpTag implements SimpleTag {
    private PageContext pageContext;
    //Web容器调用NO1
    public void setJspContext(JspContext pc) {
        System.out.println("setJspContext()");
        pageContext = (PageContext) pc;
    }
    //Web容器调用NO2
    public void doTag() throws JspException, IOException {
        System.out.println("doTag()");
        //取得HttpServletRequest请求对象
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        //取得客户端的IP地址
        String ip = request.getRemoteAddr();
        //取得out(JspWriter)对象
        JspWriter out = pageContext.getOut();
        //向浏览器输出
        out.write("<font size='44' color='red'>"+ip+"</font>");
    }
    public JspTag getParent() {
        return null;
    }
    public void setJspBody(JspFragment jspBody) {
    }
    public void setParent(JspTag parent) {
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:choose>标签处理类
public class ChooseTag extends SimpleTagSupport {
    /*
     * isDO表示其子标签是否需要执行,多者选其一个执行
     * false:表示未执行过
     * true:表示执行过
     */
    private boolean isDO = false;
    public boolean isDO() {
        return isDO;
    }
    public void setDO(boolean isDO) {
        this.isDO = isDO;
    }
    public void doTag() throws JspException, IOException {
        //执行标签体
        this.getJspBody().invoke(null);
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:when test="${age<16}">标签处理类
public class WhenTag extends SimpleTagSupport {
    private boolean test;
    public void setTest(boolean test) {
        this.test = test;
    }
    public void doTag() throws JspException, IOException {
        //取得父标签
        ChooseTag chooseTag = (ChooseTag) this.getParent();
        //取得父标签执行的状态
        boolean isDO = chooseTag.isDO();
        //判段[子标签为true,同时父标签标志位是未执行]
        if(test && !isDO){
            //执行标签体
            this.getJspBody().invoke(null);
            //设置父标签标志位为已执行过
            chooseTag.setDO(true);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:otherwise>标签处理类
public class OtherwiseTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        ChooseTag chooseTag = (ChooseTag) this.getParent();
        //父标签标志位是未执行过
        if(!chooseTag.isDO()){
            //执行标签体
            this.getJspBody().invoke(null);
            //修改父标签标志位为已执行过
            chooseTag.setDO(true);
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import java.io.StringWriter;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:upper>标签处理类
public class UpTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        
        //将"abcd"暂时存放在缓存中
        JspFragment jspFragment = this.getJspBody();
        
        //定义一个字符串缓存
        StringWriter writer = new StringWriter();
        jspFragment.invoke(writer);
        
        //从缓存中取得"abcd"
        String temp = writer.getBuffer().toString();
        
        //将缓存中的"abcd"转成"ABCD"
        temp = temp.toUpperCase();
        
        //将"ABCD"输到浏览器
        PageContext pageContext = (PageContext) this.getJspContext();
        JspWriter out = pageContext.getOut();
        out.write("<font color='red'>"+temp+"</font>");
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:skip>标签处理类
public class SkipTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        //取得标签体的内容
        JspFragment jspFragment = this.getJspBody();
        //执行标签体的内容,并将其输出到浏览器
        jspFragment.invoke(null);
        //抛出SkipPageExcetion,导到标签体后的内容不执行
        throw new SkipPageException();
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:referer url="(从自于)" error="(盗链者)">标签处理类
public class RefererTag extends SimpleTagSupport {
    private String url;
    private String error;
    public void setUrl(String url) {
        this.url = url;
    }
    public void setError(String error) {
        this.error = error;
    }
    public void doTag() throws JspException, IOException {
        
        //取得请求和响应对象
        PageContext pageContext = (PageContext) this.getJspContext();
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
        
        //取得请求头[referer]
        String referer = request.getHeader("referer");
        
        //判段
        if(referer!=null && url.equals(referer)){
            //允许下载,即执行标签体
            this.getJspBody().invoke(null);
        }else{
            //你是盗链者,进入广告页面
            try {
                request.getRequestDispatcher(error).forward(request,response);
            } catch (ServletException e) {
                e.printStackTrace();
            }
        }
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import java.io.StringWriter;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:filter>标签处理类
public class FilterTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        JspFragment jspFragment = this.getJspBody();
        StringWriter writer = new StringWriter();
        jspFragment.invoke(writer);
        String temp = writer.getBuffer().toString();
        //结果必定是转义后的字符串
        temp = filter(temp);
        PageContext pageContext = (PageContext) this.getJspContext();
        pageContext.getOut().write(temp);
    }
    public 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());
    }
}
package cn.itcast.web.jsp.tag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

//<simple:login username password/>标签处理类
public class LoginTag extends SimpleTagSupport {
    private String username;
    private String password;
    public void setUsername(String username) {
        this.username = username;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public void doTag() throws JspException, IOException {
        PageContext pageContext = (PageContext) this.getJspContext();
        JspWriter out = pageContext.getOut();
        out.write("<table border='1' align='center'>");
            out.write("<caption><h1>用户登录</h1></caption>");
            out.write("<tr>");
                out.write("<th>用户名</th>");
                out.write("<td><input type='text' name='"+username+"'/></td>");
            out.write("</tr>");
            out.write("<tr>");
                out.write("<th>密码</th>");
                out.write("<td><input type='password' name='"+password+"'/></td>");
            out.write("</tr>");
            out.write("<tr>");
                out.write("<td colspan='2' align='center'><input type='submit' value='提交'/></td>");
            out.write("</tr>");
        out.write("</table>");
    }
}
package cn.itcast.web.jsp.jstl;

public class User {
    private String username;
    private Address address;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}
<?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">
    <tlib-version>1.0</tlib-version>
    <short-name>simple</short-name>
    <uri>http://java.sun.com/jsp/jstl/simple</uri>

    <tag>
        <name>ip</name>
        <tag-class>cn.itcast.web.jsp.tag.IpTag</tag-class>
        <body-content>empty</body-content>
    </tag>

    <tag>
        <name>execute</name>
        <tag-class>cn.itcast.web.jsp.tag.ExecuteTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>

    <tag>
        <name>skip</name>
        <tag-class>cn.itcast.web.jsp.tag.SkipTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>

    <tag>
        <name>for1</name>
        <tag-class>cn.itcast.web.jsp.tag.For1Tag</tag-class>
        <body-content>scriptless</body-content>
    </tag>

    <tag>
        <name>upper</name>
        <tag-class>cn.itcast.web.jsp.tag.UpTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>

    <tag>
        <name>for2</name>
        <tag-class>cn.itcast.web.jsp.tag.For2Tag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>count</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>for3</name>
        <tag-class>cn.itcast.web.jsp.tag.For3Tag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>var</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>begin</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>end</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>step</name>
            <required>false</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>referer</name>
        <tag-class>cn.itcast.web.jsp.tag.RefererTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>url</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>error</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>if</name>
        <tag-class>cn.itcast.web.jsp.tag.IfTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>choose</name>
        <tag-class>cn.itcast.web.jsp.tag.ChooseTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>
    <tag>
        <name>when</name>
        <tag-class>cn.itcast.web.jsp.tag.WhenTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
    <tag>
        <name>otherwise</name>
        <tag-class>cn.itcast.web.jsp.tag.OtherwiseTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>

    <tag>
        <name>foreach</name>
        <tag-class>cn.itcast.web.jsp.tag.ForeachTag</tag-class>
        <body-content>scriptless</body-content>
        <attribute>
            <name>var</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>items</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

    <tag>
        <name>filter</name>
        <tag-class>cn.itcast.web.jsp.tag.FilterTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>

    <tag>
        <name>login</name>
        <tag-class>cn.itcast.web.jsp.tag.LoginTag</tag-class>
        <body-content>empty</body-content>
        <attribute>
            <name>username</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>password</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
</taglib>

*6 JSTL标准标签库
  1)<c:out value/default/escapeXml/>

属性名

是否支持EL

属性类型

属 性 描 述

value

true

Object

指定要输出的内容

escapeXml

true

Boolean

指定是否将>、<、&、'、" 等特殊字符进行HTML编码转换后再进行输出。默认值为true

default

true

Object

指定如果value属性的值为null/””时所输出的默认值

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import="cn.itcast.web.jsp.jstl.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
    <%
        Address address = new Address();
        address.setLocation("广州");
        User user = new User();
        user.setUsername("丝丝");
        user.setAddress(address);
        session.setAttribute("user",user);
    %>
      用户名: <c:out value="${user.username}" default="无名士"/><br/>
      地址:<c:out value="${user.address.location}"/>
      <hr/>
      <c:out value="<a href='#'>下载</a>" escapeXml="false"/>
  </body>
</html>

  2)<c:set var/value/scope/target/propety/>

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

属性名

是否支持EL

属性类型

属 性 描 述

value

true

Object

用于指定属性值

var

false

String

用于指定要设置的Web域属性的名称

scope

false

String

用于指定属性所在的Web域

target

true

Object

用于指定要设置属性的对象,这个对象必须是JavaBean对象或java.util.Map对象

property

true

string

用于指定当前要为对象设置的属性名称

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import="cn.itcast.web.jsp.jstl.*" %>
<%@ page import="java.util.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
    <%-- 
      <jsp:useBean id="user" class="cn.itcast.web.jsp.jstl.User" scope="page"/>
    <c:set target="${user}" property="username" value="叮叮"/>
    用户名:<c:out value="${user.username}"/>
    --%>
    
    <jsp:useBean id="map" class="java.util.HashMap" scope="page"/>
    <c:set target="${map}" property="key" value="1"/>
    <c:set target="${map}" property="value" value="jack"/>
    用户ID号:<c:out value="${map.key}"/><br/>
    用户姓名:<c:out value="${map.value}"/><br/>
    
  </body>
</html>

     3)<c:remove var/scope/>

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

    其语法格式如下:<c:remove var="varName" [scope="{page|request|session|application}"] />

<%@ page language="java" 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>
  <body>
   <%
           session.setAttribute("username","杰克");
   %>
   
   <c:remove var="username" scope="session"/>
   <%-- 
   --%>
   
   欢迎<c:out value="${username}" default="无名士"/>光临
   
   
  </body>
</html>

  4)<c:catch var/>

    <c:catch>标签用于捕获嵌套在标签体中的内容抛出的异常,其语法格式如下:<c:catch [var="varName"]>nested actions</c:catch>

<%@ page language="java" 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>
  <body>
      
      <c:catch var="myException">
          <%
            Integer.parseInt("abc");          
          %>
    </c:catch>
    
    错误原因:<c:out value="${myException.message}"/>
   
  </body>
</html>

  5)<c:if var/test/scope/>

<%@ page language="java" 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>
  <body>
      <c:if var="condition" test="${10>5}" scope="request">
          10大于5
      </c:if>    
      <jsp:forward page="value.jsp"/>
  </body>
</html>
<%@ page language="java" 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>
  <body>
      结果为:${condition}    
      
   
  </body>
</html>

     <c:if test=“”>标签可以构造简单的“if-then”结构的条件表达式

属性名

是否支持EL

属性类型

属 性 描 述

test

true

boolean

决定是否处理标签体中的内容的条件表达式

var

false

String

用于指定将test属性的执行结果保存到某个Web域中的某个属性的名称

scope

false

String

指定将test属性的执行结果保存到哪个Web域中

  6)<c:chooose/>

<%@ page language="java" 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>
  <body>
      <c:set var="age" value="${param.age}" scope="page"/>
      <c:choose>
        <c:when test="${age<16}">
            你未成年
        </c:when>
        <c:otherwise>
            你已成年
        </c:otherwise>      
      </c:choose>    
  </body>
</html>

       <c:when test/>
    <c:otherwise/>
    ${param.age}表示取得请求参数age的值

    <c:choose>标签用于指定多个条件选择的组合边界,它必须与<c:when>和<c:otherwise>标签一起使用。使用<c:choose>,<c:when>和<c:otherwise>三个标签,可以构造类似 “if-else if-else” 的复杂条件判断结构。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:set value="${param.count}" var="count“  />
<c:choose>
    <c:when test="${count == 0}">
        对不起,没有符合您要求的记录。
    </c:when>
    <c:otherwise>
        符合您要求的记录共有${count}条.
    </c:otherwise>
</c:choose>

     7)<c:forEach var/items/begin/end/step/varStatus="表示迭代过程中每个元素的状态信息,例如是否为第一项,最后项..."

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
    <%
        List<String> stringList = new ArrayList<String>();
        stringList.add("汽车");
        stringList.add("房子");
        stringList.add("新闻");
        stringList.add("娱乐");
        application.setAttribute("STRINGLIST",stringList);
    %>      
    
    <c:forEach var="s" items="${STRINGLIST}" varStatus="status">
        ${status.index}-${status.count}-${s}-${status.first}-${status.last}<br/>
    </c:forEach>

  </body>
</html>

    <c:forEach>标签用于对一个集合对象中的元素进行循环迭代操作,或者按指定的次数重复迭代执行标签体中的内容。

属性名

是否支持EL

属性类型

属 性 描 述

var

false

String

指定将当前迭代到的元素保存到page这个Web域中的属性名称

items

true

任何支持的类型

将要迭代的集合对象

varStatus

false

String

指定将代表当前迭代状态信息的对象保存到page这个Web域中的属性名称

begin

true

int

如果指定items属性,就从集合中的第begin个元素开始进行迭代,begin的索引值从0开始编号;如果没有指定items属性,就从begin指定的值开始迭代,直到end值时结束迭代

end

true

int

参看begin属性的描述

step

true

int

指定迭代的步长,即迭代因子的迭代增量

    <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>标签的最大好处。

    http://localhost:808/servlet/MyServlet?name=“中国”

    示例:<c:param name=“name” value=“中国" />

    <c:url>标签

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

属性名

是否支持EL

属性类型

属 性 描 述

value

true

String

指定要构造的URL,/表示day15

       

var

false

String

指定将构造出的URL结果保存到Web域中的属性名称

scope

false

String

指定将构造出的URL结果保存到哪个Web域中

<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
    <%-- a标签是基本标签 --%>
    <a href="/day17/value.jsp?country=<%=URLEncoder.encode("中国","UTF-8")%>">
        传统方式传中文
    </a>
      <hr/>
      
      <%-- c:url不是基本标签,底层对应标签处理类,以转发方式进行 --%>
      <c:url var="myURL" value="/value.jsp" scope="page">
          <c:param name="country" value="中国"/>
      </c:url>
    <a href="${myURL}">      
          现代方式传中文
      </a>
  </body>
</html>

     <c:redirect>标签

    <c:redirect>标签用于将当前的访问请求转发或重定向到其他资源,它可以根据url属性所指定的地址,执行类似<jsp:forward>这个JSP标准标签的功能,将访问请求转发到其他资源;或执行response.sendRedirect()方法的功能,将访问请求重定向到其他资源。

属性名

是否支持EL

属性类型

属 性 描 述

url

true

String

指定要转发或重定向到的目标资源的URL地址

       
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <body>
    <c:redirect url="/value.jsp">
        <c:param name="country" value="美国"/>
        <c:param name="tel" value="XXX"/>
    </c:redirect>
  </body>
</html>
原文地址:https://www.cnblogs.com/sunhan/p/3542136.html