JavaWeb详解(第六篇)之JSTL标签简介
Posted 穆瑾轩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb详解(第六篇)之JSTL标签简介相关的知识,希望对你有一定的参考价值。
JavaWeb详解(第六篇)之JSTL标签简介
1、JSTL概述
1.1、什么是JSTL
JSTL全称是指JavaServer Pages Standard Tag Library(JSP 标准标签库),提供了一系列的JSP标签,可以应用于各种领域,如:基本输入输出、流程控制、循环、XML 文件剖析、数据库查询及国际化和文字格式标准化的应用等,是一个不断完善的开放源代码的 JSP 标签库。
JSTL 由五个不同功能的标签库组成:
功能范围 | URI | 前缀 |
---|---|---|
核心标签库--重点 | Oracle Java Technologies | Oracle | c |
格式化 | Oracle Java Technologies | Oracle | fmt |
函数 | Oracle Java Technologies | Oracle | fn |
数据库(不使用) | Oracle Java Technologies | Oracle | sql |
XML(不使用) | Oracle Java Technologies | Oracle | x |
1.2、为什么要使用JSTL
EL 表达式主要是为了替换 jsp 中的表达式脚本, 而代码脚本这些并没有得到很好的优化,为了取代传统直接在页面上嵌入 Java 程序的做法,以提高程序可读性、维护性和便捷性,于是有了JSTL标签库,它使得整个 jsp 页面变得更佳简洁。
1.3、如何使用
1)先导入 jstl 标签库的 jar 包
注:下载地址
taglibs-standard-impl-1.2.5.jar
taglibs-standard-spec-1.2.5.jar(tomcat也需要此包)
2)第二步, 使用 taglib 指令引入标签库
<!--CORE 标签库-->
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!--FMT 标签库-->
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!--FUNCTIONS 标签库-->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!--XML 标签库-->
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<!--SQL 标签库-->
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
2、core标签库的使用
core标签库是JSTL的核心标签库,实现了最基本的功能:流程控制、迭代输出等操作!
核心标签主要有:
标签 | 描述 |
---|---|
<c:if> | 构造简单的“if-then”结构的条件表达式 |
<c:choose> | 指定多个条件选择的组合边界,它必须与<c:when> 和<c:otherwise> 标签一起使用 |
<c:when> | <c:choose> 的子标签,用来判断条件是否成立 |
<c:otherwise> | <c:choose> 的子标签,接在<c:when> 标签后,当<c:when> 标签判断为false时被执行 |
<c:forEach> | 基础迭代标签,接受多种集合类型 |
<c:forTokens> | 根据指定的分隔符来分隔内容并迭代输出 |
<c:out> | 输出一段文本到浏览器中 |
<c:set> | 把某一个对象存在指定的域范围内 |
<c:remove> | 用于删除数据 |
<c:catch> | 用于捕获嵌套在标签体中的内容抛出的异常 |
<c:url> | 在JSP页面中构造一个URL地址 |
<c:import> | 检索一个绝对或相对 URL,然后将其内容暴露给页面 |
<c:redirect> | 重定向至一个新的URL |
<c:param> | 用来给包含或重定向的页面传递参数 |
2.1、c:if
<c:if>
标签用于简单的条件语句。
<c:if>
标签的属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
test | 条件 | 是 | 无 |
var | 用于存储条件结果的变量 | 否 | 无 |
scope | var属性的作用域 | 否 | page |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>jstl_core.jsp</h1>
<%
request.setAttribute("i", 12);
%>
<%--test属性必须存在--%>
<c:if test="${empty param.user}">
<h3>没有获取到user参数</h3>
</c:if>
<c:if test="${i==12}">
<h3>12==12</h3>
</c:if>
<%
String amind="Admin";
request.setAttribute("amind",amind);
%>
<%--var变量:用来存储test的评定结果,scope属性指定var变量的域--%>
<c:if test="${requestScope.amind=='Admin'}" var="condition" scope="session">
匹配正确哦
</c:if><br>
获取存储值sessionScope.condition:${sessionScope.condition}<br>
获取存储值requestScope.condition:${requestScope.condition}
</body>
</html>
案例效果:
2.2、c:choose、c:when、c:otherwise
用于复杂判断的<c:choose>、<c:when>、<c:otherwise>
标签
<c:choose>
标签没有属性,可以被认为是父标签, <c:when>
、 <c:otherwise>
将作为其子标签来使用。
<c:when>
标签等价于“ if”语句,它包含一个 test属性,该属性表示需要判断的条件。
<c:otherwise>
标签没有属性,它等价于“ else”语句。
<c:when>
标签的属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
test | 条件 | 是 | 无 |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>jstl_core.jsp</h1>
<c:choose>
<c:when test="${sex eq 'M'}">
男
</c:when>
<c:when test="${sex eq 'F'}">
女
</c:when>
<c:otherwise>
性别不明
</c:otherwise>
</c:choose>
</body>
</html>
2.3、c:forEach、c:forTokens
JSTL所支持的迭代标签有两个,分别是<c:forEach>
和<c:forTokens>
。<c:forTokens>
标签则通过指定分隔符将字符串分隔为一个数组然后迭代它们。
<c:forEach>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
items | 要被循环的信息 | 否 | 无 |
begin | 开始的元素(0=第一个元素,1=第二个元素) | 否 | 0 |
end | 最后一个元素(0=第一个元素,1=第二个元素) | 否 | Last element |
step | 每一次迭代的步长 | 否 | 1 |
var | 代表当前条目的变量名称 | 否 | 无 |
varStatus | 代表循环状态的变量名称 | 否 | 无 |
<c:forTokens>
标签与<c:forEach>
标签有相似的属性,不过<c:forTokens>
还有另一个属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
delims | 分隔符 | 是 | 无 |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>jstl_core.jsp</h1>
<%--从“ 1”循环到“ 10”,并将循环中变量“ i”显示在页面上--%>
<c:forEach var="i" begin="1" end="10" step="1">
${i}<br />
</c:forEach>
<%--输出10以内的质数--%>
<c:forEach var="i" begin="1" step="2" end="10">
${i}
</c:forEach>
<br>
<%--遍历数组--%>
<%
request.setAttribute("arr", new String[]{"18610541354","18688886666","18699998888"});
%>
<c:forEach items="${ requestScope.arr }" var="item">
${ item } <br>
</c:forEach>
<%
Map<String,Object> map = new HashMap<String, Object>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
request.setAttribute("map", map);
%>
<%--遍历 Map 集合--%>
<c:forEach items="${ requestScope.map }" var="entry">
${entry.key} = ${entry.value}<br>
</c:forEach>
</body>
</html>
使用案例二:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:forTokens</h1>
<span>遍历:google,runoob,taobao</span><br>
<c:forTokens items="google,runoob,taobao" delims="," var="name">
<c:out value="${name}"/><p>
</c:forTokens>
</body>
</html>
案例效果:
2.4、c:out
<c:out>
用于在 JSP中显示数据就像是 <%= scripting-language %>
一样
<c:out>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 要输出的内容 | 是 | 无 |
default | 输出的默认值 | 否 | 主体中的内容 |
escapeXml | 是否忽略XML特殊字符 | 否 | true |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:out</h1>
以前的写法:
<%out.println("hello world"); %>
<%request.setAttribute("abc", "你好1");%><br>
<%-- 如果属性域对象中有相同的属性名,c:out 的优先级是:
pageContext>request>session>application
它出色的地方就多了两个属性,default和escapeXml属性。
如果我们用到这两个属性,我们就使用该标签,如果没有用到这两个属性就用EL表达式就可以了
--%>
<c:out value="hello world"></c:out>
<c:out value="${abc}" default="没有值" escapeXml="false"></c:out>
</body>
</html>
案例效果:
2.5、c:set
<c:set>
标签用于为变量或 JavaBean中的变量属性赋值的工作
<c:set>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 要存储的值 | 否 | 主体的内容 |
target | 要修改的属性所属的对象 | 否 | 无 |
property | 要修改的属性 | 否 | 无 |
var | 存储信息的变量 | 否 | 无 |
scope | var属性的作用域 | 否 | Page |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:out</h1>
<c:set var="abc1" value="中国,北京" scope="request"></c:set>
<c:out value="${abc1 }"></c:out><br>
等价于:
<%
request.setAttribute("abc", "中国,北京");
%>
${abc }
</body>
</html>
2.6、c:remove
<c:remove>
标签用于删除存在于 scope中的变量。
<c:remove>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
var | 要移除的变量名称 | 是 | 无 |
scope | 变量所属的作用域 | 否 | 所有作用域 |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:remove</h1>
<c:set var="name" scope="session" value="username"/>
<p>name 变量值: <c:out value="${name}"/></p>
<c:remove var="name"/>
<p>移除 name 变量后的值: <c:out value="${name}"/></p>
</body>
</html>
2.7、c:catch
<c:catch>
用于异常捕获
<c:catch>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
var | 用来储存错误信息的变量 | 否 | None |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:catch</h1>
<c:catch var="myexception">
<%int a=9/0; %>
</c:catch>
<c:out value="${myexception}"></c:out>
</body>
</html>
案例效果:
2.8、c:url
<c:url>
标签将URL格式化为一个字符串,然后存储在一个变量中。
<c:url>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 基础URL | 是 | 无 |
context | 本地网络应用程序的名称 | 否 | 当前应用程序 |
var | 代表URL的变量名 | 否 | Print to page |
scope | var属性的作用域 | 否 | Page |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:url</h1>
<%-- 产生一个字符串,并不是一个可以点的链接,并把他存入var的遍历中 --%>
<c:url value="http://www.baidu.com" var="bd"/>
${bd }
<br>
<a href="${bd }">百度一下</a>
</body>
</html>
2.9、c:import
<c:import>
标签提供了所有<jsp:include>
行为标签所具有的功能,同时也允许包含绝对URL。
<c:import>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
url | 待导入资源的URL,可以是相对路径和绝对路径,并且可以导入其他主机资源 | 是 | 无 |
context | 当使用相对路径访问外部context资源时,context指定了这个资源的名字。 | 否 | 当前应用程序 |
charEncoding | 所引入的数据的字符编码集 | 否 | ISO-8859-1 |
var | 用于存储所引入的文本的变量 | 否 | 无 |
scope | var属性的作用域 | 否 | page |
varReader | 可选的用于提供java.io.Reader对象的变量 | 否 | 无 |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:import</h1>
<c:import url="/el.jsp"></c:import>
<hr>
<c:import url="http://www.baidu.com" var="thisPage" charEncoding="UTF-8"/>
<a href="${thisPage }"></a>
</body>
</html>
案例效果:
2.10、c:redirect、c:param
<c:redirect>
用于页面的重定向,该标签的作用相当于 response.setRedirect方法的工作。并且支持<c:param>
标签。
<c:param>
用来为包含或重定向的页面传递参数。可用于<c:url>
、 <c:redirect>
中。
<c:redirect>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
url | 目标URL | 是 | 无 |
context | 紧接着一个本地网络应用程序的名称 | 否 | 当前应用程序 |
<c:param>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
name | URL中要设置的参数的名称 | 是 | 无 |
value | 参数的值 | 否 | Body |
使用案例:
<%@ page contentType="text/html;charset=GBK" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>c:redirect</h1>
<c:redirect url="el.jsp">
<c:param name="userName" value="RW" />
</c:redirect>
</body>
</html>
案例效果:
3、fmt标签库的使用
fmt标签库,提供了对国际化(I18N)的支持,它可以根据发出请求的客户端地域的不同来显示不同的语言,所以也叫做国际化标签库。同时还提供了格式化数据和日期的方法。
fmt标签主要有:
标签 | 描述 |
---|---|
<fmt:formatNumber> | 使用指定的格式或精度格式化数字 |
<fmt:parseNumber> | 解析一个代表着数字,货币或百分比的字符串 |
<fmt:formatDate> | 使用指定的风格或模式格式化日期和时间 |
<fmt:parseDate> | 解析一个代表着日期或时间的字符串 |
<fmt:bundle> | 绑定资源 |
<fmt:setLocale> | 指定地区 |
<fmt:setBundle> | 绑定资源 |
<fmt:timeZone> | 指定时区 |
<fmt:setTimeZone> | 指定时区 |
<fmt:message> | 显示资源配置文件信息 |
<fmt:requestEncoding> | 设置request的字符编码 |
3.1、fmt:formatNumber
<fmt:formatNumber>
用于格式化数字,百分比,货币。
<fmt:formatNumber>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 要显示的数字 | 是 | 无 |
type | NUMBER,CURRENCY,或 PERCENT类型 | 否 | Number |
pattern | 指定一个自定义的格式化模式用与输出 | 否 | 无 |
currencyCode | 货币码(当type="currency"时) | 否 | 取决于默认区域 |
currencySymbol | 货币符号 (当 type="currency"时) | 否 | 取决于默认区域 |
groupingUsed | 是否对数字分组 (TRUE 或 FALSE) | 否 | true |
maxIntegerDigits | 整型数最大的位数 | 否 | 无 |
minIntegerDigits | 整型数最小的位数 | 否 | 无 |
maxFractionDigits | 小数点后最大的位数 | 否 | 无 |
minFractionDigits | 小数点后最小的位数 | 否 | 无 |
var | 存储格式化数字的变量 | 否 | Print to page |
scope | var属性的作用域 | 否 | page |
使用案例:
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>fmt:formatNumber</h1>
<%-- <fmt:setLocale value="zh_CN"/>
注:如果要实现国际化,那么编码格式要设置为utf-8,否则¥符号无法显示
--%>
<c:set var="balance" value="120000.2309" />
<p>Formatted Number (1): <fmt:formatNumber value="${balance}"
type="currency"/></p>
<p>Formatted Number (2): <fmt:formatNumber type="number"
maxIntegerDigits="3" value="${balance}" /></p>
<p>Formatted Number (3): <fmt:formatNumber type="number"
pattern="#,#00.0#" value="${balance}" /></p>
<p>Formatted Number (7): <fmt:formatNumber type="percent"
maxIntegerDigits="3" value="${balance}" /></p>
<p>Currency in USA :
<fmt:setLocale value="en_US"/>
<fmt:formatNumber value="${balance}" type="currency"/></p>
</body>
</html>
案例效果:
3.2、fmt:formatDate
<fmt:formatDate>
标签用于使用不同的方式格式化日期。
<fmt:formatDate>
标签有如下属性:
属性 | 描述 | 是否必要 | 默认值 |
---|---|---|---|
value | 要显示的日期 | 是 | 无 |
type | DATE, TIME, 或 BOTH | 否 | date |
dateStyle | FULL, LONG, MEDIUM, SHORT, 或 DEFAULT | 否 | default |
timeStyle | FULL, LONG, MEDIUM, SHORT, 或 DEFAULT | 否 | default |
pattern | 自定义格式模式 | 否 | 无 |
timeZone | 显示日期的时区 | 否 | 默认时区 |
var | 存储格式化日期的变量名 | 否 | 显示在页面 |
scope | 存储格式化日志变量的范围 | 否 | 页面 |
使用案例:
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>fmt:formatDate</h1>
<c:set var="now" value="<%=new java.util.Date()%>" />
<p>日期格式化 (1): <fmt:formatDate type="time"
value="${now}" /></p>
<p>日期格式化 (2): <fmt:formatDate type="date"
value="${now}" /></p>
<p>日期格式化 (3): <fmt:formatDate type="both"
value="${now}" /></p>
<p>日期格式化 (4): <fmt:formatDate type="both"
dateStyle="short" timeStyle="short"
value="${now}" /></p>
<p>日期格式化 (5): <fmt:formatDate type="both"
dateStyle="medium" timeStyle="medium"
value="${now}" /></p>
<p>日期格式化 (6): <fmt:formatDate type="both"
dateStyle="long" timeStyle="long"
value="${now}" /></p>
<p>日期格式化 (7): <fmt:formatDate pattern="yyyy-MM-dd"
value="${now}" /></p>
</body>
</html>
案例效果:
4、functions标签库的使用
JSTL Functions标签库包含一系列标准函数(EL函数),大部分是通用的字符串处理函数。
函数 | 描述 |
---|---|
fn:contains() | 测试输入的字符串是否包含指定的子串 |
fn:containsIgnoreCase() | 测试输入的字符串是否包含指定的子串,大小写不敏感 |
fn:endsWith() | 测试输入的字符串是否以指定的后缀结尾 |
fn:escapeXml() | 跳过可以作为XML标记的字符 |
fn:indexOf() | 返回指定字符串在输入字符串中出现的位置 |
fn:join() | 将数组中的元素合成一个字符串然后输出 |
fn:length() | 返回字符串长度 |
fn:replace() | 将输入字符串中指定的位置替换为指定的字符串然后返回 |
fn:split() | 将字符串用指定的分隔符分隔然后组成一个子字符串数组并返回 |
fn:startsWith() | 测试输入字符串是否以指定的前缀开始 |
fn:substring() | 返回字符串的子集 |
fn:substringAfter() | 返回字符串在指定子串之后的子集 |
fn:substringBefore() | 返回字符串在指定子串之前的子集 |
fn:toLowerCase() | 将字符串中的字符转为小写 |
fn:toUpperCase() | 将字符串中的字符转为大写 |
fn:trim() | 移除首尾的空白符 |
使用案例:
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<title>jstl_core.jsp</title>
</head>
<body>
<h1>fn:functions</h1>
<p>containsIgnoreCase函数:${fn: containsIgnoreCase ("Tomcat","CAT")}</p>
<p>startsWith函数:${fn: startsWith ("Tomcat","Tom")}</p>
<p>indexOf函数:${fn: indexOf ("Tomcat","cat")}</p>
<p>substring函数:${ fn: substring ("Tomcat",0,3)}</p>
</body>
</html>
案例效果:
5、xml标签库的使用
JSTL XML标签库提供了创建和操作XML文档的标签。
标签 | 描述 |
---|---|
<x:out> | 与<%= ... >,类似,不过只用于XPath表达式 |
<x:parse> | 解析 XML 数据 |
<x:set> | 设置XPath表达式 |
<x:if> | 判断XPath表达式,若为真,则执行本体中的内容,否则跳过本体 |
<x:forEach> | 迭代XML文档中的节点 |
<x:choose> | <x:when> 和<x:otherwise> 的父标签 |
<x:when> | <x:choose> 的子标签,用来进行条件判断 |
<x:otherwise> | <x:choose> 的子标签,当<x:when> 判断为false时被执行 |
<x:transform> | 将XSL转换应用在XML文档中 |
<x:param> | 与<x:transform> 共同使用,用于设置XSL样式表 |
6、sql标签库的使用
JSTL SQL标签库提供了与关系型数据库(Oracle,mysql,SQL Server等等)进行交互的标签。
标签 | 描述 |
---|---|
<sql:setDataSource> | 指定数据源 |
<sql:query> | 运行SQL查询语句 |
<sql:update> | 运行SQL更新语句 |
<sql:param> | 将SQL语句中的参数设为指定值 |
<sql:dateParam> | 将SQL语句中的日期参数设为指定的java.util.Date 对象值 |
<sql:transaction> | 在共享数据库连接中提供嵌套的数据库行为元素,将所有语句以一个事务的形式来运行 |
由于xml、和sql标签库用的并不多,我们着重介绍一下自定义标签。
7、自定义标签
7.1、为什么要使用自定义标签
JSTL标签库只提供了简单的输出等功能,这些功能毕竟有限,有很多复杂的逻辑可能并不好用这些标准的标签库去实现,所以呢需要自定义标签。在Struts中也有自己的一套标签。
7.2、如何去实现自定义标签
我们去观察下标准标签库中已有的core标签库,他有一些实体类和一个c.tld。
所以要实现自定义标签需要做:
1)定义一个类,现实相应的接口;
2)在项目的WEB-INF文件夹中新建一个tld文件;
要想让一个类成为标签类,就必须实现Jsptag接口,目前已知的实现类及接口有:
a)如果要自定义一个标签我们需要去实现Tag接口或SimaapleTag接口;
b)如果要自定义一个有标签体有属性的标签,继承 BodyTagSupport类
c)如果要自定义一个没有标签体的标签,继承TagSupport类
当然看自己需求,决定使用哪个接口或类。
7.3、自定义标签的生命周期
首先我们看一个案例:
1)新建一个MyTag1类实现Tag接口
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
public class MyTag1 implements Tag{
/**
* 当WEB容器执行到自定义标签的结束标记时,调用doEndTag()方法
*/
@Override
public int doEndTag() throws JspException {
System.out.println("我调用了doEndTag");
return 0;
}
/**
* 当WEB容器执行到自定义标签的开始标记时,调用doStartTag()方法
*/
@Override
public int doStartTag() throws JspException {
System.out.println("我调用了doStartTag");
return 0;
}
@Override
public Tag getParent() {
return null;
}
/**
* 当WEB容器执行完自定义标签后,标签处理器类会驻留在内存中,直至停止WEB应用时,WEB容器才会调用release()方法
*/
@Override
public void release() {
System.out.println("我调用了release");
}
/**
* 由服务器调用将pageContext对象传递给标签处理器类,
* 使得标签处理器类可以通过pageContext对象与JSP页面进行通信
*/
@Override
public void setPageContext(PageContext arg0) {
System.out.println("我调用了setPageContext");
}
/**
* setPageContext()后调用,如果当前标签没有父标签,则传入null
*/
@Override
public void setParent(Tag arg0) {
System.out.println("我调用了setParent");
}
}
2)新建一个myTag.tld
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.2</tlib-version>
<short-name>my</short-name>
<uri>http://www.mytag.com</uri>
<tag>
<name>mytag1</name>
<tag-class>com.cn.tag.MyTag1</tag-class>
<!--标签体内容:
empty:无标签体
scriptless:标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素
tagdependent:表示标签体交由标签本身去解析处理。
JSP:jsp2.0已不支持,表示可以是java脚本、标签,也可以是el表达式
-->
<body-content>empty</body-content>
</tag>
</taglib>
3)新建一个myjstl.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@taglib prefix="my" uri="http://www.mytag.com" %>
<!--引入这个标签库使用的uri-->
<!DOCTYPE html>
<html>
<head>
<title>myjstl.jsp</title>
</head>
<body>
<h1>自定义标签</h1>
<p><my:mytag1/></p>
</body>
</html>
4)案例执行效果
整个执行过程:
a)JSP引擎遇到自定义标签,首先创建标签处理器类的实例对象;
b)然后调用setPageContext()方法,将pageContext对象传递给标签处理器类,使得标签处理器类可以通过pageContext对象与JSP页面进行通信;
c)setPageContext()方法执行完后,调用setParent()方法,将当前标签的父标签传递给当前处理器类,如果当前标签没有父标签,则传入null;
d)当WEB容器执行到自定义标签的开始标记时,调用doStartTag()方法;
e)当WEB容器执行到自定义标签的结束标记时,调用doEndTag()方法;
f)当WEB容器执行完自定义标签后,标签处理器类会驻留在内存中,直至停止WEB应用时,WEB容器才会调用release()方法;
7.4、自定义标签的实现
7.4.1、TagSupport类实现自定义标签
TagSupport是Tag的一个模板类,实现了pageContext,parent的getter、setter方法以及一些其他的功能。
使用案例:
1)新建一个MyTag2类继承TagSupport
package com.cn.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;
public class MyTag2 extends TagSupport{
private String defaultValue;
private String value;
/**
* 属性对应的方法
* @param value
*/
public void setValue(String value) {
this.value = value;
}
/**
* 属性对应的方法
* @param value
*/
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
@Override
public int doEndTag() throws JspException {
// TODO Auto-generated method stub
return super.doEndTag();
}
/**
* 标签中静态常量:
* EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流
* SKIP_BODY:告诉服务器不要处理正文内容
* EVAL_PAGE:让服务器继续执行页面
* SKIP_PAGE:让服务器不要处理剩余的页面
* EVAL_BODY_AGAIN:让服务器继续处理正文内容,只有doAfterBody方法可以返回
* EVAL_BODY_BUFFERED:BodyTag接口的字段,在doStartTag()返回
*
* EVAL_BODY_INCLUDE、SKIP_BODY一般由doStartTag()返回,
* 而EVAL_PAPGE、SKIP_PAGE由doEndTag()返回
*/
@Override
public int doStartTag() throws JspException {
//获取到request对象
String str = value;
if (value == null || "".equals(value)) {
str = defaultValue;
}
JspWriter jspWriter = pageContext.getOut();
try {
jspWriter.write(str);
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}
2)myTag.tld中加入
<tag>
<name>mytag2</name>
<tag-class>com.cn.tag.MyTag2</tag-class>
<body-content>empty</body-content>
<attribute>
<name>value</name>
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>defaultValue</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
3)使用自定义标签
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@taglib prefix="my" uri="http://www.mytag.com" %>
<!DOCTYPE html>
<html>
<head>
<title>myjstl.jsp</title>
</head>
<body>
<h1>自定义标签</h1>
<p><my:mytag2 value="myValue"/></p>
<p><my:mytag2 value="" defaultValue="default"/></p>
</body>
</html>
4)案例效果
7.4.2、BodyTagSupport类实现自定义标签
BodyTagSupport继承了TagSupport类实现了BodyTag接口,也能获取到标签体的内容,所以说如果要自定义一个有标签体有属性的标签,应该继承 BodyTagSupport类。
他的生命周期:doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()
使用案例:
1)新建一个MyTag3类
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class MyTag3 extends BodyTagSupport{
@Override
public BodyContent getBodyContent() {
return super.getBodyContent();
}
public int doAfterBody() throws JspException {
// TODO Auto-generated method stub
BodyContent content = getBodyContent();
String str = content.getString();
System.out.println(str);
if(str != null){
String name = "";
if(str.startsWith("$toUpperCase(") && str.endsWith(")"))
{
String para = str.substring(13,str.length()-1);
if(para!=null && !"".equals(para)) {
name = para.toUpperCase();
}
}
JspWriter out = getPreviousOut();
try {
out.print(name==null?str:name);
} catch (IOException e) {
e.printStackTrace();
}
}
return SKIP_BODY;
}
}
2)myTag.tld
<tag>
<name>mytag3</name>
<tag-class>com.cn.tag.MyTag3</tag-class>
<body-content>scriptless</body-content>
</tag>
3)myjstl.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib prefix="my" uri="http://www.mytag.com" %>
<!DOCTYPE html>
<html>
<head>
<title>myjstl.jsp</title>
</head>
<body>
<h1>自定义标签</h1>
<%
request.setAttribute("key", "value");
pageContext.setAttribute("key", "value1");
%>
<p>${key }</p>
<my:mytag3>$toUpperCase(${key})</my:mytag3>
</body>
</html>
4)案例效果
以上是关于JavaWeb详解(第六篇)之JSTL标签简介的主要内容,如果未能解决你的问题,请参考以下文章
Java实战之04JavaWeb-04JSPEL表达式JSTL标签库