JavaWeb-JSTL

序言

JSTL全称为 JSP Standard Tag Library ,即JSP标准标签库。JSTL作为最基本的标签库,提供了一系列的JSP标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理、数据的格式化等等!

【为什么要使用JSTL呢】

1、EL表达式不够完美,需要JSTL的支持!在JSP中,我们前面已经用到了EL表达式,体会到了EL表达式的强大功能:使用EL表达式可以很方便地引用一些JavaBean以及其属性,不会抛出NullPointerException之类的错误!但是,EL表达式非常有限,它不能遍历集合,做逻辑的控制。这时,就需要JSTL的支持了
2、Scriptlet的可读性,维护性,重用性都十分差!JSTL与HTML代码十分类似,遵循着XML标签语法,使用JSTL让JSP页面显得整洁,可读性非常好,重用性非常高,可以完成复杂的功能!
3、在JSP中不推荐使用scriptlet(即JSP脚本中的<% Java代码 %>)输出,推荐使用JSP标签。

【JSTL一共包含四大标签库】:

1、core:核心标签库,我们学习的重点;
2、fmt:格式化标签库,只需要学习两个标签即可;
3、sql:数据库标签库,不需要学习了,它过时了;
4、xml:xml标签库,不需要学习了,它过时了。

【使用taglib指令导入标签库】:

除了JSP动作标签外,使用其他第三方的标签库都需要:

1、导入jstl.jar和standard.jar开发包导包;
2、在使用标签的JSP页面中使用taglib指令导入标签库;

下面是导入JSTL的core标签库:

<%@ taglib prefix="c"uri="http://java.sun.com/jstl/core" %>

(1) prefix=”c”
指定标签库的前缀,这个前缀可以随便给值,但大家都会在使用core标签库时指定前缀为c;

(2) uri=”http://java.sun.com/jstl/core”
指定标签库的uri,它不一定是真实存在的网址,但它可以让JSP找到标签库的描述文件。


1、Core标签库

core标签库是JSTL的核心标签库,实现了最基本的功能流程控制、迭代输出等操作!core标签库的前缀一般是c,是最常用的JSTL标签。

以下是在JSP的语法包含JSTL核心库:

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

有以下核心JSTL标签:
这里写图片描述

(1) out 标签

<c:out>标签具有以下属性:
这里写图片描述
<c:out>标签的用法:

(1)输出常量:可在属性value中直接赋值
(2)输出变量:变量不存在时可配合defalut属性输出默认值,还可以通过属性escapeXml控制转义字符的输出方式。

实例:
这里写图片描述
结果:
这里写图片描述

(2) set 标签

<c:set>标签具有以下属性:
这里写图片描述
var属性操作的是Integer、Double、Float、String等类型的数据,target属性操作的是JavaBean或Map对象的数据,scope代表的是Web域,value是值,property是对象的属性

<c:set>标签的用法:

   (1)存值到scope中:可将值以变量形式存放在指定的范围中(2种方式)

   (2)存值到JavaBean的属性中

【实例】

实例类Person的代码:

/**
 * 实体类Person
 * @author Administrator
 */
public class Person {
    private String name;
    private int age;
    private String hobby;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getHobby() {
        return hobby;
    }

    public void setHobby(String hobby) {
        this.hobby = hobby;
    }
}

NewFile.jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入JSTL标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- 导入实例类Person -->
<jsp:useBean id="person" class="com.entity.Person" />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSTL使用</title>
</head>
<body>
     <h1>JSTL标签的使用</h1>
     <hr>
     <!-- 存值到scope中 -->
     <!-- 方式一 -->
     <c:set value="today" var="day" scope="session" />
     <c:out value="${day}" /><br/>  

     <!-- 方式二 value的值写在标签体里边-->
     <c:set var="love" scope="application" >football</c:set>
     <c:out value="${love}" /><br/> 

     <!-- 通过set标签向person对象中赋值 -->
     <c:set target="${person}" property="name" value="Jack"/>
     <c:out value="${person.name}" /><br/>  
     <c:set target="${person}" property="age" >22</c:set>
     <c:out value="${person.age}" /><br/>       
</body>
</html>

结果:
这里写图片描述

(3) remove 标签

<c:remove>标签是删除变量,无论是从指定的范围内或范围内的变量(如果没有指定范围)。这个动作通常是不特别有帮助,但它可以帮助确保一个JSP范围内的资源,它负责清理。

<c:remove>标签具有以下属性:
这里写图片描述
<c:remove>标签的用法:移除掉某个变量,var属性是必选的;scope属性是可选的。

【实例】

<%--创建出JavaBean对象,设置为session范围的属性--%> 
<jsp:useBean id="person" class="domain.Person" scope="session"/> 

<%--获取到person对象,设置age属性的值为32--%> 
<c:set target="${person}" property="age" value="32"/>

${person.age} 
<br> 

<%--删除session属性--%> 
<c:remove var="person" scope="session"></c:remove> 
${person.age==null?"存在session的person对象被删除了!":"我还在呢!"}

效果:
这里写图片描述

(4) catch 标签

该标签主要用来处理程序中产生的异常。

<c:catch>标签具有以下属性:
这里写图片描述
【实例】

 <%--创建出JavaBean对象,设置为session范围的属性--%> 
 <jsp:useBean id="person" class="domain.Person" scope="session"/> 

 <c:catch var="message"> 
 <%--target属性只能是EL表达式,现在我是字符串,获取不到对象,肯定会抛出异常的!--%>       
   <c:set target="person" property="age" value="32"/> 
 </c:catch> 

 ${message}

效果:
这里写图片描述

(5) if 标签

<c:if>标签计算表达式,只有当表达式的值为true,则显示其主体内容。

<c:if>标签具有以下属性:
这里写图片描述
<c:if>标签的用法:

   同程序中的if作用相同,用来实现分支条件控制。
   text属性用于存放判断的条件,一般使用EL表达式来编写;
   var属性是指定名称用来存放判断的结果类型为true或false;
   scope属性是用来存放var属性存放的范围。

【实例】根据用户输入的成绩进行等级判断
这里写图片描述
这个例子没有做完,使用<c:if>标签实现比较繁琐,我们后面可以使用<c:choose>标签以及<c:when>标签来实现。

(6) choose 标签

if标签没有else的功能,如果需要类似于Java中的if else流程就需要使用choose标签。when标签的test为true时,会执行这个when的内容。当所有when标签的test都为false时,才会执行otherwise标签的内容。

通常这三个标签被放在一起使用。<c:choose>标签嵌套在<c:when>标签和<c:otherwise>标签的外面作为他们的父标签来使用;其中<c:choose>标签和<c:when>标签也可以单独一起组合使用。

<c:choose><c:otherwise>标签没有任何属性。<c:when>标记有一个属性,如下:
这里写图片描述
【实例】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入JSTL标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSTL使用</title>
</head>
<body>
     <h1>JSTL标签的使用</h1>
     <hr>
     <!-- 标签的用法 -->
     <form action="NewFile.jsp" method="post">
           <input type="text" name="score" value="${param.score}" />
           <input type="submit" />
     </form>
     <c:choose>
           <c:when test="${param.score>=90&&param.score<=100}">
                  <c:out value="优秀" />
           </c:when>
           <c:when test="${param.score>=80&&param.score<90}">
                  <c:out value="良好" />
           </c:when>
           <c:when test="${param.score>=70&&param.score<80}">
                  <c:out value="中等" />
           </c:when>
           <c:when test="${param.score>=60&&param.score<70}">
                  <c:out value="及格" />
           </c:when>
           <c:when test="${param.score>=0&&param.score<60}">
                  <c:out value="不及格" />
           </c:when>
           <c:otherwise>
                  <c:out value="你的输入有问题!" />
           </c:otherwise>
     </c:choose>
</body>
</html>

结果:
这里写图片描述

(7) foreach 标签

forEach当前就是循环标签了,forEach标签有多种两种使用方式:

使用循环变量,指定开始和结束值,类似for(int i = 1; i <= 10; i++) {};
循环遍历集合,类似for(Object o : 集合);

其属性为:
这里写图片描述
<c:forEach>标签的用法:

   根据循环条件遍历集合(Collection)中的元素。
   var属性是设定变量名用于存储从集合中取出元素(必须无默认值);
   items属性是指定要遍历的几个(必须无默认值);
   begin属性和end属性是用于指定遍历的起始位置和终止位置(有默认);
   step属性指定循环的步长(有默认);
   varStatus属性通过index、count、first和last几个状态值,描述begin和end子集中的元素的状态。

【循环遍历】

<!--部分遍历-->
<c:set var="sum" value="0" /> 
<c:forEach var="i" begin="1" end="10"> 
    <c:set var="sum" value="${sum + i}" /> 
</c:forEach>
<c:out value="sum = ${sum }"/>

<!--部分遍历并且指定步长-->
<c:set var="sum" value="0" />
<c:forEach var="i" begin="1" end="10" step ="2">
    <c:set var="sum" value="${sum + i}" />
</c:forEach>
<c:out value="sum = ${sum }"/>

【遍历集合或数组方式】

<%
String[] names = {"zhangSan", "liSi", "wangWu", "zhaoLiu"};
pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
    <c:out value="name: ${item }"/><br/>
</c:forEach>

【遍历List】

<%
    List<String> names = new ArrayList<String>();
    names.add("zhangSan");
    names.add("liSi");
    names.add("wangWu");
    names.add("zhaoLiu");
    pageContext.setAttribute("ns", names);
%>
<c:forEach var="item" items="${ns }">
    <c:out value="name: ${item }"/><br/>
</c:forEach>

【遍历Map】

<%
    Map<String,String> stu = new LinkedHashMap<String,String>();
    stu.put("number", "N_1001");
    stu.put("name", "zhangSan");
    stu.put("age", "23");
    stu.put("sex", "male");
    pageContext.setAttribute("stu", stu);
%>
<c:forEach var="item" items="${stu }">
    <c:out value="${item.key }: ${item.value }"/><br/>
</c:forEach>

forEach标签还有一个属性:varStatus,这个属性用来指定接收“循环状态”的变量名,例如:<forEach varStatus=”vs” …/>,这时就可以使用vs这个变量来获取循环的状态了。

count:int类型,当前以遍历元素的个数;
index:int类型,当前元素的下标;
first:boolean类型,是否为第一个元素;
last:boolean类型,是否为最后一个元素;
current:Object类型,表示当前项目。
<c:forEach var="item" items="${ns }" varStatus="vs">
    <c:if test="${vs.first }">第一行:</c:if>
    <c:if test="${vs.last }">最后一行:</c:if>
    <c:out value="第${vs.count }行: "/>
    <c:out value="[${vs.index }]: "/>
    <c:out value="name: ${vs.current }"/><br/>
</c:forEach>

(8) forTokens 标签

该标签类似于String类的split()和for循环的一种集合

它与forEach标签非常相似,都有begin、end、step、items、var、varStatus属性,不同的是forTokens标签的items属性里面是字符串,这个字符串会被delims属性的内容分割成多个字符串

<c:forTokens items="zhongfucheng,ouzicheng,xiaoming,xiaohong" var="name" delims="," > 
    ${name}
</c:forTokens>

效果图:
这里写图片描述

(9) import 标签

<c:import>标签提供<jsp:include>动作标签的所有的功能动作,但也可以包含绝对URL。例如,允许使用导入标签包含的内容从一个不同的Web站点或FTP服务器。

<jsp:include>标签的区别:只能包含同一个Web应用中的文件,而<c:import>标签可以包含其他Web应用中的文件,甚至是网络上的资源。

<c:import>标签具有以下属性:
这里写图片描述
<c:import>标签的用法:

   可以把其他静态或动态文件包含到本JSP页面。

   url属性指的是被导入资源的URL路径;

   context属性指的是相同服务器下其他Web工程,必须以"/"开头;

   var属性指的是以String类型存入被包含文件的内容;

   scope属性指的是var变量的JSP范围;

   charEncoding属性指的是被导入文件的编码格式 ;

   varReade属性指的是以Reader类型存储被包含文件内容;

   context属性引入的内容是webapps下的其他的Web project。

实例代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入JSTL标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSTL使用</title>
</head>
<body>
     <h1>JSTL标签的使用</h1>
     <hr>
     <!-- import标签的用法 -->
     <!-- 导入网络上的绝对路径 -->
     <c:catch var="error09">
            <c:import url="https://www.baidu.com" charEncoding="UTF-8"  />
     </c:catch>
     <c:out value="${error09}" /><br/>
     <!-- 导入相对路径文件 -->
     <c:catch var="error08">
            <c:import url="test.txt" charEncoding="UTF-8" />
     </c:catch>
     <c:out value="${error08}" /><br/>
     <!-- var和scope属性的用法 -->
     <c:catch var="error07">
            <c:import url="test.txt" var="test" scope="session" charEncoding="UTF-8" />
     </c:catch>
     <c:out value="${error07}" />
     <c:out value="import标签存储的test字符串变量值为:${sessionScope.test}" /><br/>
     <!-- content属性的用法 -->
     <c:catch var="error06">
            <c:import url="/date.jsp" context="/FirstWebApp" charEncoding="UTF-8" />
     </c:catch>
     <c:out value="${error06}" />   
</body>
</html>

结果:
这里写图片描述

(10) redirect 标签

<c:redirect>标签将浏览器重定向到一个备用URL提供自动URL重写,它支持上下文相关的URL和支持<c:param>标签。

<c:redirect>标签具有以下属性:
这里写图片描述
<c:param>标签允许适当的URL请求参数到指定的URL和任何必要的URL编码。在一个<c:param>标签的name属性表示参数的名称,value属性表示的参数值。

<c:param>标签具有以下属性:
这里写图片描述
<c:redirect>标签的用法:

   该标签用来实现请求的重定向,同事可以在url中加入指定的参数;
   url属性用于指定重定向页面的地址,可以是一个String类型的绝对路径或相对地址;
   context属性用于导入其他Web应用中的页面。

【实例】
这里写图片描述

(11) url 标签

url标签十分实用!在浏览器禁用Cookie的时候,我们之前学Servlet时解决办法是:response.encodeURL()。url标签也可以实现这样的功能,再配合param标签使用,就十分实用了!

<c:url>标签格式化成一个字符串格式的URL,并将其存储到变量中。这个标签会在必要时自动执行URL重写。var属性指定的变量将包含格式化的URL。JSTL url标签只是response.encodeURL()方法的调用一个替代方法。URL标记提供的唯一的真正的优势是正确的URL编码,包括子<c:param>标签指定的任何参数。

<c:url>标记具有以下属性:
这里写图片描述
<c:url>标签的用法:

   该标签用于动态生成一个String类型的URL,可以同<c:param>标签共同使用,也可以使用HTML中的<a>标签实现超链接。
   var属性是将url路径存储在的变量中;
   value属性表示url路径值;
   scope属性是var变量的范围。

【实例1】
这里写图片描述
【实例2】

<c:url value="2.jsp" var="url"> 
<c:param name="name" value="中国!"> 
</c:param> </c:url> <a href="${url}">我经过了URL地址重写!</a>

效果:
这里写图片描述


2、格式化标签

使用JSTL格式标签来格式化和显示文本,日期,时间和数字的,国际化的网站。以下是在您的JSP的语法,包括

格式化库:

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

以下是格式化JSTL标签列表:
这里写图片描述
【格式化时间】

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
......
<%
    Date date = new Date();
    pageContext.setAttribute("d", date);
%>
<fmt:formatDate value="${d }" pattern="yyyy-MM-dd HH:mm:ss"/>

【格式化数字】

<%
    double d1 = 3.5;
    double d2 = 4.4; 
    pageContext.setAttribute("d1", d1);
    pageContext.setAttribute("d2", d2);
%>
<fmt:formatNumber value="${d1 }" pattern="0.00"/><br/>
<fmt:formatNumber value="${d2 }" pattern="#.##"/>

3、SQL标签

JSTL的SQL标签库标签可以交互关系型数据库(如Oracle,MySQL或Microsoft SQL Server的关系数据库管理系统)。以下是在您的JSP语法包括JSTL SQL库:

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

以下是SQL JSTL标签的列表:
这里写图片描述

4、XML标签

JSTL XML标记提供了一种创建和操作XML文档的JSP为中心的方式。以下是在您的JSP的语法包括JSTL XML库。

JSTL XML标记库具有自定义标签与XML数据交互。这包括XML解析,转换XML数据,流控制,基于XPath表达式。

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

以下是XML JSTL标签列表:
这里写图片描述

5、JSTL函数

JSTL包括一些标准功能,其中大部分是常见的字符串操作函数。以下是在JSP的语法包函JSTL函数库:

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

以下是JSTL函数列表:
这里写图片描述
【实例】

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 导入JSTL标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- 导入JSTL函数库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSTL使用</title>
</head>
<body>
    <h1>JSTL函数的使用</h1>
    <hr>
    <!-- contains函数使用 -->
    <c:out value=" Hello Word字符串是否包含Hello:${fn:contains('Hello World','Hello')}" /><br>
    <c:out value=" Hello Word字符串是否包含test:${fn:contains('Hello World','test')}" /><br>
    <!-- containsIgnoreCase函数使用 -->
    <c:out value=" Hello Word字符串是否包含hello(忽略大小写):${fn:containsIgnoreCase('Hello World','hello')}" /><br>
    <c:out value=" Hello Word字符串是否包含WORLD(忽略大小写):${fn:containsIgnoreCase('Hello World','WORLD')}" /><br>
    <!-- endsWith和startsWith函数使用 -->
    <c:out value=" Hello Word字符串是否以World结尾:${fn:endsWith('Hello World','World')}" /><br>
    <c:out value=" Hello Word字符串是否以Hello开头:${fn:startsWith('Hello World','Hello')}" /><br>
    <!-- escapeXml函数使用 -->
    <c:out value="${fn:escapeXml('<book>谁的青春不迷茫</book>')}"  /><br>
    <c:out value="<book>谁的青春不迷茫</book>"  /><br>
    <!-- indexOf函数使用 -->
    <c:out value=" Hello Word字符串中Hello出现的index值:${fn:indexOf('Hello World','Hello')}" /><br>
</body>
</html>

结果:
这里写图片描述


7、自定义标签

(1) 步骤

其实我们在JSP页面中使用标签就等于调用某个对象的某个方法一样,例如:<c:if test=””>,这就是在调用对象的方法一样。自定义标签其实就是自定义类一样!

步骤1、定义标签处理类:必须是Tag或SimpleTag的实现类;
步骤2、编写标签库描述符文件(TLD);

SimpleTag接口是JSP2.0中新给出的接口,用来简化自定义标签,所以现在我们基本上都是使用SimpleTag。Tag是老的,传统的自定义标签时使用的接口,现在不建议使用它了。

(2) SimpleTag接口

SimpleTag接口内容如下:

void doTag():标签执行方法;
JspTag getParent():获取父标签;
void setParent(JspTag parent):设置父标签
void setJspContext(JspContext context):设置PageContext
void setJspBody(JspFragment jspBody):设置标签体对象;

请记住,万物皆对象!在JSP页面中的标签也是对象!你可以通过查看JSP的源码,清楚的知道,所有标签都会变成对象的方法调用。标签对应的类我们称之为“标签处理类”!

【标签的生命周期】

1、当容器(Tomcat)第一次执行到某个标签时,会创建标签处理类的实例;
2、然后调用setJspContext(JspContext)方法,把当前JSP页面的pageContext对象传递给这个方法;
3、如果当前标签有父标签,那么使用父标签的标签处理类对象调用setParent(JspTag)方法;
4、如果标签有标签体,那么把标签体转换成JspFragment对象,然后调用setJspBody()方法;
5、每次执行标签时,都调用doTag()方法,它是标签处理方法。

HelloTag.java

public class HelloTag implements SimpleTag {
    private JspTag parent;
    private PageContext pageContext;
    private JspFragment jspBody;

    public void doTag() throws JspException, IOException {
        pageContext.getOut().print("Hello Tag!!!");
    }
    public void setParent(JspTag parent) {
        this.parent = parent;
    }
    public JspTag getParent() {
        return this.parent;
    }
    public void setJspContext(JspContext pc) {
        this.pageContext = (PageContext) pc;
    }
    public void setJspBody(JspFragment jspBody) {
        this.jspBody = jspBody;
    }
}

(3) 标签库描述文件TLD

  标签库描述文件是用来描述当前标签库中的标签的!标签库描述文件的扩展名为tld,你可以把它放到WEB-INF下,这样就不会被客户端直接访问到了。

hello.tld

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xml="http://www.w3.org/XML/1998/namespace" 
    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 ">

    <tlib-version>1.0</tlib-version>
    <short-name>ywq</short-name>
    <uri>http://www.ywq.cn/tags</uri>
    <tag>
        <name>hello</name>
        <tag-class>cn.ywq.tag.HelloTag</tag-class>
        <body-content>empty</body-content>
    </tag>
</taglib>

(4) 使用标签

在页面中使用标签分为两步:

(1) 使用taglib导入标签库;
(2) 使用标签;

即:

<%@ taglib prefix="it" uri="/WEB-INF/hello.tld" %>
       ......
<it:hello/>

(5) 继承SimpleTagSupport

  继承SimpleTagSuppport要比实现SimpleTag接口方便太多了,现在你只需要重写doTag()方法,其他方法都已经被SimpleTagSuppport完成了。

public class HelloTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        this.getJspContext().getOut().write("<p>Hello SimpleTag!</p>");
    }
}

(6) 有标签体的标签

我们先来看看标签体内容的可选值:

<body-content>元素的可选值有:

empty:无标签体。
JSP:传统标签支持它,SimpleTag已经不再支持使用<body-content>JSP</body-content>。标签体内容可以是任何东西:EL、JSTL、<%=%>、<%%>,以及html;
scriptless:标签体内容不能是Java脚本,但可以是EL、JSTL等。在SimpleTag中,如果需要有标签体,那么就使用该选项;
tagdependent:标签体内容不做运算,由标签处理类自行处理,无论标签体内容是EL、JSP、JSTL,都不会做运算。这个选项几乎没有人会使用!

自定义有标签体的标签需要:

获取标签体对象:JspFragment jspBody = getJspBody();;
把标签体内容输出到页面:jspBody.invoke(null);
tld中指定标签内容类型:scriptless。
public class HelloTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        PageContext pc = (PageContext) this.getJspContext();
        HttpServletRequest req = (HttpServletRequest) pc.getRequest();
        String s = req.getParameter("exec");
        if(s != null && s.endsWith("true")) {
            JspFragment body = this.getJspBody();
            body.invoke(null);
        }
    }
}
<tag>
        <name>hello</name>
        <tag-class>cn.ywq.tags.HelloTag</tag-class>
        <body-content>scriptless</body-content>
    </tag>
 <itcast:hello>
        <h1>哈哈哈~</h1>
    </itcast:hello>

(7) 不执行标签下面的页面内容

  如果希望在执行了自定义标签后,不再执行JSP页面下面的东西,那么就需要在doTag()方法中使用SkipPageException。

public class SkipTag extends SimpleTagSupport {
    public void doTag() throws JspException, IOException {
        this.getJspContext().getOut().print("<h1>只能看到我!</h1>");
        throw new SkipPageException();
    }
}
    <tag>
        <name>skip</name>
        <tag-class>cn.ywq.tags.SkipTag</tag-class>
        <body-content>empty</body-content>
    </tag>
  <itcast:skip/>
  <h1>看不见我!</h1>

(9) 带有属性的标签

一般标签都会带有属性,例如<c:iftest=””>,其中test就是一个boolean类型的属性。完成带有属性的标签需要:

在处理类中给出JavaBean属性(提供get/set方法);
在TLD中部属相关属性。
public class IfTag extends SimpleTagSupport {
    private boolean test;
    public boolean isTest() {
        return test;
    }
    public void setTest(boolean test) {
        this.test = test;
    }
    @Override
    public void doTag() throws JspException, IOException {
        if(test) {
            this.getJspBody().invoke(null);
        }
    }
}
<tag> 
        <name>if</name> 
        <tag-class>cn.ywq.IfTag</tag-class> 
        <body-content>scriptless</body-content>
        <attribute>
            <name>test</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute> 
    </tag>
<%
    pageContext.setAttribute("one", true);
    pageContext.setAttribute("two", false);
%>
<it:if test="${one }">xixi</it:if>
<it:if test="${two }">haha</it:if>
<it:if test="true">hehe</it:if>

猜你喜欢

转载自blog.csdn.net/weixin_39190897/article/details/82561645
今日推荐