JavaWeb開發(fā)之JSTL標(biāo)簽庫的使用、 自定義EL函數(shù)、自定義標(biāo)簽(帶屬性的、帶標(biāo)簽體的)
JSTL
JSTL簡介:
JSTL的全稱:JSP Standard Tag Library,JSP標(biāo)準(zhǔn)標(biāo)簽庫
JSTL的作用:
提供給Java Web開發(fā)人員一個(gè)標(biāo)準(zhǔn)通用的標(biāo)簽函數(shù)庫
和EL來取代傳統(tǒng)直接在頁面上嵌入Java程序(Scripting)的做法,以提高程序可讀性、維護(hù)性和方便性
JSTL的版本:
JSTL的主要版本是1.0、1.1和1.2(區(qū)別不大)
1.0版本EL表達(dá)式還沒有納入官方規(guī)范
1.1和1.2版本EL表達(dá)式已經(jīng)納入了官方規(guī)范
JSTL1.1 下載相應(yīng)的jar包
JSTL的下載
JSTL主要由Apache組織的Jakarta Project實(shí)現(xiàn)
http://tomcat.apache.org/taglibs/standard/
容器必須支持Servlet2.4且JSP2.0以上的版本
JavaEE1.4
JSTL導(dǎo)入jar包
解壓縮后將lib中的jstl.jar、standard.jar 復(fù)制到WEB應(yīng)用程序的WEB-INF\lib下

JSTL標(biāo)簽庫
- 核心標(biāo)簽庫(core)---c(重點(diǎn))
- XML(x:操作xml的標(biāo)簽庫)
- SQL(sql標(biāo)簽庫)
- FMT(fmt:國際化標(biāo)簽庫)
- JSTL函數(shù)(EL函數(shù))el
JSTL快速入門
導(dǎo)入jar包(jstl.jar和standard.jar)
其中jstl.jar是編譯后的Java類文件,standard.jar定義的是標(biāo)準(zhǔn)接口
新建JSP的頁面
在頁面中引入核心標(biāo)簽庫
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
JSTL標(biāo)簽庫關(guān)于導(dǎo)入版本的問題
http://java.sun.com/jsp/core 1.1或者1.2版本(使用該版本)
http://java.sun.com/jstl/core 1.0版本(不支持EL表達(dá)式)

<c:out>標(biāo)簽輸出常量或者域范圍中的變量(value屬性,使用EL表達(dá)式)
輸出默認(rèn)值(default屬性)
默認(rèn)HTML標(biāo)簽不轉(zhuǎn)義(escapeXml)
| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |
| value | true | Object | 指定要輸出的內(nèi)容 |
| escapeXml | true | Boolean | 指定是否將>、<、&、'、" 等 特殊字符進(jìn)行HTML編碼轉(zhuǎn)換 后再進(jìn)行輸出。默認(rèn)值是true。 |
| default | true | Object | 指定如果value屬性的值為null時(shí)所輸出的默認(rèn)值 |
<!-- c:out 輸出數(shù)據(jù)到瀏覽器 -->
<c:out value="Hello c out "></c:out>
Hello c out
<!-- 輸出一個(gè)變量 -->
<c:set var="m" value="10" scope="page"/>
<c:out value="${m}"></c:out>
${m }
<!-- 轉(zhuǎn)義HTML 默認(rèn)轉(zhuǎn)義,通過設(shè)置escapeXml 為false 不進(jìn)行轉(zhuǎn)義-->
<c:out value="<a href='xxx'>link</a>" />
${fn:escapeXml("<a href='xxx'>link</a>") }
<!-- 允許輸出默認(rèn)值 ,如果city不存在,輸出北京-->
<c:out value="${city}" default="北京"></c:out>
${empty city?"北京":city }
在WebRoot下新建jstl文件夾,在文件夾下新建out.jsp
實(shí)例代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>傳統(tǒng)方式</h4>
<%= "Hello" %>
<%
int a = 10;
request.setAttribute("name", "xy");
%>
<%= a %>
<h4>JSTL的方式 </h4>
<c:out value="Hello"></c:out>
<c:out value="${name }"></c:out>
<!-- "" -->
<c:out value="${ city }" default="北京"></c:out>
<c:out value="<a href='#'>超鏈接</a>" escapeXml="false"/>
<c:out value="<a href='#'>超鏈接2</a>" escapeXml="true"/>
</body>
</html>

<c:set>標(biāo)簽
- 向4個(gè)域中存入值。(var value scope屬性)
- 設(shè)置Web域中的java.util.Map 類型的屬性對象或JavaBean類型的屬性對象的屬性(target property value屬性)
| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |
| value | true | Object | 用于指定屬性 |
| var | false | String | 用于指定要設(shè)置的Web域?qū)傩缘拿Q |
| scope | false | String | 用于指定屬性所在的Web域 |
| target | true | Object | 用于指定要設(shè)置屬性的對象,這個(gè)對象必須是 JavaBean對象或java.util.Map對象 |
| property | true | String | 用于指定當(dāng)前要為對象設(shè)置的屬性名稱 |
在WebRoot/jstl下新建set.jsp
代碼如下:
<%@page import="cn.itcast.vo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>傳統(tǒng)方式</h4>
<%
pageContext.setAttribute("name", "10", pageContext.REQUEST_SCOPE);
%>
<%
User user = new User();
user.setUsername("美美");
user.setPassword("123");
request.setAttribute("user", user);
%>
${ user.username }
<h4>JSTL方式</h4>
<c:set var="i" value="10" scope="request" ></c:set>
${ i }
<c:set target="${ user }" property="username" value="小鳳"></c:set>
${ user.username }
</body>
</html>

<c:remove>標(biāo)簽
<c:remoive>標(biāo)簽用于刪除各種Web域中的屬性
其語法格式如下:
<c:remove var="varName" [scope="{page|request|session|application}"]>
如果不設(shè)置,默認(rèn)是pageContext域范圍內(nèi)查找刪除值。
用法示例:
<%
request.setAttribute("age",20);
// 刪除age
request.removeAttribute("age");
%>
<c:set var="age" value="20" scope="request"></c:set>
<c:remove var="age" scope="request"/>
在WebRoot/jstl目錄下新建remove.jsp
實(shí)例代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>傳統(tǒng)方式</h4>
<%
request.setAttribute("name", "美美");
request.removeAttribute("name");
%>
<c:set var="name" value="小鳳" scope="page"></c:set>
${ name }
<c:remove var="name" scope="page"/>
${name }
</body>
</html>

<c:catch>標(biāo)簽
- <c:catch>標(biāo)簽用于捕獲嵌套在標(biāo)簽中的內(nèi)容拋出的異常,其語法格式如下:<c:catch [var="varName"]> nested actions </c:catch>
- var屬性用于標(biāo)識<c:catch>標(biāo)簽捕獲的異常對象,它將保存在page這個(gè)web域中。
關(guān)鍵代碼:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ page contentType="text/html;charset=gb2312" %> <c:catch var="myex“ > <% 10/0; %> </c:catch>
異常:<c:out value="${myex}" /> ${myex}<br />
異常 myex.getMessage:<c:out value="${myex.message}" /><br />
異常 myex.getCause:<c:out value="${myex.cause}" /><br />
異常 myex.getStackTrace:<c:out value="${myex.stackTrace}" />
在WebRoot/jstl下新建catch.jsp
實(shí)例代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>傳統(tǒng)方式</h4>
<%
try{
}catch(Exception e){
e.printStackTrace();
}
%>
<h4>JSTL的方式</h4>
<c:catch var="e">
<%
int a = 10/0;
%>
</c:catch>
${ e.message }
</body>
</html>

<c:if>標(biāo)簽
<c:if test=""> 標(biāo)簽可以構(gòu)造簡單的"if-then"結(jié)構(gòu)的條件表達(dá)式
| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |
| test | true | boolean | 決定是否處理標(biāo)簽體中的內(nèi)容的條件表達(dá)式 |
| var | false | String | 用于指定將test屬性的執(zhí)行結(jié)果保存到某個(gè)Web域中的某個(gè)屬性的名稱 |
| scope | false | String | 指定將test屬性的執(zhí)行結(jié)果保存到哪個(gè)Web域中 |
注意:沒有<c:else>
在WebRoot/jstl下新建if.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>傳統(tǒng)方式</h4>
<%
int a = 10;
if(a >= 10){
out.print("a >= 10");
}else{
out.print("a < 10");
}
%>
<h4>JSTL方式</h4>
<c:set var="i" value="10" scope="page"></c:set>
<c:if test="${ i ge 10 }" var="x" scope="page">
i >= 10
</c:if>
<c:if test="${ i lt 10 }">
i < 10
</c:if>
${ x }
</body>
</html>

<c:choose>
<c:choose>標(biāo)簽用于指定多個(gè)條件選擇的組合邊界,它必須與<c:when>和<c:otherwise>標(biāo)簽一起使用。使用<c:choose>,<c:when>,<c:otherwise>三個(gè)標(biāo)簽,可以構(gòu)造類似于"if-else if-else"的復(fù)雜條件判斷結(jié)構(gòu)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:set value="${param.count}" var="count“ /> pageContext(count,2)
<c:choose>
<c:when test="${count == 0}">
對不起,沒有符合您要求的記錄。
</c:when>
<c:otherwise>
符合您要求的記錄共有${count}條.
</c:otherwise>
</c:choose>
在WebRoot/jstl目錄下新建choose.jsp
代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>獲取參數(shù)</h4>
<%= request.getParameter("username") %>
<h4>傳統(tǒng)方式</h4>
<%
int a = 10;
if(a >= 10 ){
out.print("a >= 10");
}else if(a < 10){
out.print("a < 10");
}else{
out.print("其他");
}
%>
<h4>JSTL方式</h4>
<c:set var="i" value="10" scope="page"></c:set>
<c:choose>
<c:when test="${ i ge 10 }">
i >= 10
</c:when>
<c:when test="${ i lt 10 }">
i < 10
</c:when>
<c:otherwise>
其他
</c:otherwise>
</c:choose>
</body>
</html>

<c:forEach>標(biāo)簽
<c:forEach>標(biāo)簽用于對一個(gè)集合對象中的元素進(jìn)行循環(huán)迭代操作,或者按指定的次數(shù)重復(fù)迭代執(zhí)行標(biāo)簽體中的內(nèi)容
| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |
| var | false | String | 指定將當(dāng)前迭代到的元素保存到page這個(gè)域中的屬性名稱 |
| varStatus | false | String | 記住用于保存迭代信息的對象 |
| items | true | 任何支持的類型 | 將要迭代的集合對象 |
| begin | true | int | 如果指定items屬性,就從集合中的第begin個(gè)元素開始進(jìn)行迭代 ,begin的索引值從0開始編號,如果沒有指定items屬性,就從 begin指定的值開始迭代,直到end值時(shí)結(jié)束迭代 |
| end | true | int | 與begin屬性類似 |
| step | true | int | 指定迭代的步長,即迭代因子的迭代增量 |
<c:forEach>遍歷集合
遍歷數(shù)組或者集合:
var:代表遍歷的每一個(gè)元素
items:要迭代的集合對象
獲取遍歷的內(nèi)容:${ xxx }
遍歷Map集合:
var:代表key與value的關(guān)系entry
items:要迭代的map集合
獲取遍歷的內(nèi)容:${ xxx.key } ----${ xxx.value }
遍歷對象集合:
var:代表遍歷的每一個(gè)對象
items:要迭代的集合
獲取遍歷的內(nèi)容: ${ xxx.對象的屬性 }
<c:forEach>迭代數(shù)據(jù)
從1遍歷到10:
var:定義變量
begin:從哪開始
end:到哪結(jié)束
step:迭代步長(相當(dāng)于x+=step)
計(jì)算從1加到10的和:
定義變量sum,值為0
通過forEach循環(huán)1到10,每循環(huán)一次加到另一個(gè)變量中
在循環(huán)中間定義變量,每次計(jì)算到該變量中
<c:set var="sum" value="0" scope="page"></c:set>
<c:forEach begin="1" end="10" step="1" var="i">
<c:set var="sum" value="${sum + i}" scope="page"></c:set>
</c:forEach>
${sum }
varStatus屬性:
記錄迭代相關(guān)的信息:
| 屬性 | 類型 | 意義 |
| index | number | 現(xiàn)在指到成員的索引 |
| count | number | 總共指到成員的總數(shù) |
| first | boolean | 現(xiàn)在指到的成員是否是第一個(gè)成員 |
| last | boolean | 現(xiàn)在指到的成員是否是最后一個(gè)成員 |
遍歷10到100的偶數(shù),每到第三個(gè)數(shù),顯示紅色:
<c:forEach begin="10" end="100" step="2" var="i" varStatus="status">
<c:if test="${status.count % 3 == 0}">
<font color="red">${i }</font>
</c:if>
<c:if test="${status.count % 3 != 0}">
<font color="blue">${i }</font>
</c:if>
</c:forEach>
在WebRoot/jstl目錄下新建forEach.jsp
實(shí)例代碼如下:
<%@page import="cn.itcast.vo.User"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>遍歷數(shù)組</h4>
<%
String [] arrs = {"美美","小鳳","芙蓉","小蒼"};
request.setAttribute("arrs", arrs);
%>
<!-- for(String s : arrs){ } -->
<c:forEach var="s" items="${ arrs }">
${ s }
</c:forEach>
<h4>遍歷集合</h4>
<%
List<String> list = new ArrayList<String>();
list.add("美美");
list.add("小鳳");
list.add("芙蓉");
list.add("小澤");
request.setAttribute("list", list);
%>
<c:forEach var="s" items="${ list }">
${ s }
</c:forEach>
<h4>遍歷Map集合</h4>
<%
Map<String,String> map = new HashMap<String,String>();
map.put("aa", "美美");
map.put("bb", "小鳳");
map.put("cc", "芙蓉");
request.setAttribute("map", map);
%>
<c:forEach var="entry" items="${ map }">
${ entry.key } -- ${ entry.value }
</c:forEach>
<h4>遍歷對象的集合</h4>
<%
List<User> uList = new ArrayList<User>();
uList.add(new User("美美","123"));
uList.add(new User("小風(fēng)","234"));
uList.add(new User("芙蓉","345"));
request.setAttribute("uList", uList);
%>
<c:forEach var="user" items="${ uList }">
${ user.username } -- ${ user.password }
</c:forEach>
<h4>迭代數(shù)據(jù)</h4>
<h4>迭代從1到10</h4>
<c:forEach var="i" begin="1" end="10" step="2">
${ i }
</c:forEach>
<h4>計(jì)算從1加到100的和</h4>
<c:set var="sum" value="0" scope="page"></c:set>
<c:forEach var="i" begin="1" end="100" step="1" varStatus="status">
<c:set var="sum" value="${ sum + i }"></c:set>
</c:forEach>
${ sum }
<h4>遍歷10到100的偶數(shù),每到第3個(gè)數(shù),顯示紅色</h4>
<c:forEach var="i" begin="10" end="100" step="2" varStatus="status">
<c:choose>
<c:when test="${ status.first }">
<font color="blue">${ i }</font>
</c:when>
<c:when test="${ status.count % 3 eq 0 }">
<font color="red">${ i }</font>
</c:when>
<c:otherwise>
${ i }
</c:otherwise>
</c:choose>
</c:forEach>
</body>
</html>

<c:forTokens>
用來切分字符串
| 名稱 | 說明 | EL | 類型 | 必須 | 默認(rèn)值 |
| var | 用來存放現(xiàn)在指到的成員 | N | String | 否 | 無 |
| items | 被迭代的字符串 | Y | String | 是 | 無 |
| delims | 定義用來分割字符串的字符 | N | String | 是 | 無 |
| varStatus | 用來存放現(xiàn)在指到的相關(guān)成員信息 | N | String | 否 | 無 |
| begin | 開始的位置 | Y | int | 否 | 0 |
| end | 結(jié)束的位置 | Y | int | 否 | 最后一個(gè) |
<c:set var="s" value="aaa,bbb,ccc" scope="page"></c:set>
<c:forTokens items="${s}" delims="," var="e">
${e }
</c:forTokens>
語法格式:
<c:forTokens items=要切分的字符串 delims=按著什么格式切分 var=定義變量 [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]> //body內(nèi)容 </c:forTokens>
在WebRoot/jstl目錄下新建forTokens.jsp
代碼如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>分隔字符串</h4>
<c:set var="i" value="aa,bb,cc" scope="page"></c:set>
<c:forTokens items="${i }" delims="," var="x">
${ x }
</c:forTokens>
</body>
</html>

<c:param>標(biāo)簽
- 在JSP頁面進(jìn)行URL的相關(guān)操作時(shí),經(jīng)常要在URL地址后面附加一些參數(shù)。<c:param>標(biāo)簽可以嵌套在<c:import>、<c:url>或<c:redirect>標(biāo)簽內(nèi),為這些標(biāo)簽所使用的URL地址附加參數(shù)。
- <c:param>標(biāo)簽在為一個(gè)URL地址附加參數(shù)時(shí),將自動(dòng)對參數(shù)值進(jìn)行URL編碼,例如:如果傳的參數(shù)值為“中國”,則將其轉(zhuǎn)換為“%d6%d0%b9%fa”后再附加到URL地址后面,這也就是使用<c:param>標(biāo)簽的最大好處
- 示例:<c:param name="name" value="value" />
<c:import>標(biāo)簽
| 名稱 | 說明 | EL | 類型 | 必須 | 默認(rèn)值 |
| url | 一文件被包含的地址 | Y | String | 是 | 無 |
| context | 項(xiàng)目虛擬路徑 | Y | String | 否 | 無 |
| var | 儲存被包含的文件的內(nèi)容(以String類型存入) | Y | String | 否 | 無 |
| scope | var變量的JSP范圍 | N | String | 否 | page |
| charEncoding | 被包含文件的內(nèi)容的編碼方式 | Y | String | 否 | 無 |
| varReader | 儲存被包含的文件的內(nèi)容(以Reader類型存入) | N | String | 否 |
<!-- 引入foreach.jsp 效果類似包含-->
<c:import url="/jstl/foreach.jsp" context="/day8"></c:import>
<hr/>
<!-- 引入不顯示,將內(nèi)容保存另一個(gè)變量中 -->
<c:import url="/jstl/foreach.jsp" context="/day8" var="content" scope="page"></c:import>
${content }
<c:import url="http://java.sun.com" >
<c:param name="test" value="1234" />
</c:import>
在WebRoot/jstl/下新建 import.jsp(包含choose.jsp 并在choose.jsp 中獲取參數(shù))
實(shí)例代碼如下:
<!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>Insert title here</title>
</head>
<body>
<h4>JSTL方式</h4>
<c:import url="/jstl/choose.jsp" context="/day13" var="i" scope="page">
<c:param name="username" value="meimei"></c:param>
</c:import>
${ i }
</body>
</html>

<c:url>標(biāo)簽
<c:url>標(biāo)簽用于在JSP頁面中構(gòu)造一個(gè)URL地址,其主要目的是實(shí)現(xiàn)URL重寫。URL重寫就是將會話標(biāo)識以參數(shù)形式附加在URL地址后面。(類似于Session追蹤 尤其是當(dāng)瀏覽器禁用cookie后,就是說實(shí)現(xiàn)了session追蹤的功能)
| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |
| value | true | String | 指定要構(gòu)造的URL |
| var | false | String | 指定將構(gòu)造出的URL結(jié)果保存到Web域中的屬性名稱 |
| scope | false | String | 指定將構(gòu)造出的URL結(jié)果保存在哪個(gè)域中 |
在WebRoot/jstl/下新建url.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>JSTL方式</h4>
<c:url var="i" value="/jstl/choose.jsp" scope="request" context="/day13">
<c:param name="username" value="xiaofeng"></c:param>
</c:url>
<c:set var="s" value="劉勛" scope="session"></c:set>
<a href="${ i }">choose</a> <br>
i= ${i } <br>
<%
String url = "/day12/index.jsp";
url = response.encodeURL(url);
%>
<!-- 將/day8/index.jsp 進(jìn)行url重寫,保存page范圍 myurl中 -->
<c:url value="/index.jsp" context="/day13" var="myurl" scope="page" />
url= <%=url %> <br>
myurl= ${myurl } <br>
<!-- 通過c:url 結(jié)合 c:param 對中文完成URL編碼 -->
<c:url value="/login" context="/day13" var="myurl2" scope="page">
<c:param name="username" value="張三"></c:param>
</c:url>
myurl2= ${myurl2 } <br>
</body>
</html>
修改choose.jsp 如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<c:out value="${s }"></c:out>
<h4>獲取參數(shù)</h4>
<%= request.getParameter("username") %>
<h4>傳統(tǒng)方式</h4>
<%
int a = 10;
if(a >= 10 ){
out.print("a >= 10");
}else if(a < 10){
out.print("a < 10");
}else{
out.print("其他");
}
%>
<h4>JSTL方式</h4>
<c:set var="i" value="10" scope="page"></c:set>
<c:choose>
<c:when test="${ i ge 10 }">
i >= 10
</c:when>
<c:when test="${ i lt 10 }">
i < 10
</c:when>
<c:otherwise>
其他
</c:otherwise>
</c:choose>
</body>
</html>
禁用瀏覽器的cookie后,運(yùn)行如下:

點(diǎn)擊choose跳轉(zhuǎn)到choose.jsp

<c:redirect>標(biāo)簽
<c:redirect>標(biāo)簽用于實(shí)現(xiàn)請求重定向
| 屬性名 | 是否支持EL | 屬性類型 | 屬性描述 |
| url | true | String | 指定要轉(zhuǎn)發(fā)或重定向到的目標(biāo)資源的URL地址 |
| context | true | String | 當(dāng)要使用相對路徑重定向到同一個(gè)服務(wù)器下的其他WEB應(yīng)用程序中的 資源時(shí),context屬性指定其他WEB應(yīng)用程序的名稱 |
注意:如果重定向第三方的網(wǎng)站時(shí)要使用絕對路徑(不能再使用Context)
<%
// 以前重定向
// response.sendRedirect("/day12/index.jsp");
%>
<c:redirect url="/index.jsp" context="/day12"></c:redirect>
在WebRoot/jstl下新建redirect.jsp
[html] view plain copy 在CODE上查看代碼片派生到我的代碼片
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ 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>Insert title here</title>
</head>
<body>
<h4>JSTL方式</h4>
<c:redirect url="/jstl/choose.jsp" context="/day13">
<c:param name="username" value="furong"></c:param>
</c:redirect>
</body>
</html>
EL函數(shù)庫
JSTL中的常用EL函數(shù)
EL函數(shù)是用來操作字符串的
由于在JSP頁面中顯示數(shù)據(jù)時(shí),經(jīng)常需要對顯示的字符串進(jìn)行處理,SUN公司針對一些常見處理定義了一套EL函數(shù)庫供開發(fā)者使用。
這些EL函數(shù)在JSTL開發(fā)包中進(jìn)行描述,因此在JSP頁面中使用SUN公司的EL函數(shù)庫,需要導(dǎo)入JSTL開發(fā)包,并在頁面中導(dǎo)入EL函數(shù)庫,如下所示:
在頁面中使用JSTL定義的EL函數(shù):
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> (可以在fn.tld文件中查看)
fn:toLowerCase
fn:toLowerCase函數(shù)將一個(gè)字符串中包含的所有字符轉(zhuǎn)換為小寫形式,并返回轉(zhuǎn)換后的字符串,它接收一個(gè)字符串類型的參數(shù),例如:
fn.toLowerCase("") 的返回值為空字符串
fn:toUpperCase
fn:toUpperCase函數(shù)將一個(gè)字符串中包含的所有字符轉(zhuǎn)換為大寫形式,并返回轉(zhuǎn)換后的字符串,它接收一個(gè)字符串類型的參數(shù)。例如:
fn:toUpperCase("")的返回值為空字符串
fn:trim
fn:trim函數(shù)刪除一個(gè)字符串的首尾的空格,并返回刪除空格后的結(jié)果字符串,它接收一個(gè)字符串類型的參數(shù)。需要注意的是,
fn:trim函數(shù)不能刪除字符串中間位置的空格
例如:fn:trim(" www.it3 15.org ")的返回值字符串是"www.it 315.org"
fn:length
fn:length函數(shù)返回一個(gè)集合或數(shù)組大小,或返回一個(gè)字符串中包含的字符的個(gè)數(shù),返回值是int類型。fn:length函數(shù)接收一個(gè)參數(shù),這個(gè)參數(shù)可以是<c:forEach>標(biāo)簽的items屬性支持的任何類型,包括任意類型的數(shù)組、java.util.Collection、java.util.Iterator、java.util.Enumeration、java.util.Map等類的實(shí)例對象和字符串。
如果fn:length函數(shù)的參數(shù)為null或者是元素個(gè)數(shù)為0的集合或數(shù)組對象,則函數(shù)返回0;如果參數(shù)是空字符串,則函數(shù)返回0;
fn:split
fn:split函數(shù)以指定字符串作為分隔符,將一個(gè)字符串分割成數(shù)組并返回這個(gè)字符串?dāng)?shù)組。
fn:split函數(shù)接收兩個(gè)字符串類型的參數(shù),第一個(gè)參數(shù)表示要分割的字符串,第二個(gè)參數(shù)表示作為分隔符的字符串。
fn:join
fn:join函數(shù)以一個(gè)字符串作為分隔符,將一個(gè)字符串?dāng)?shù)組中的所有元素合并為一個(gè)字符串并返回合并后的結(jié)果字符串。fn:join函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)是要操作的字符串?dāng)?shù)組,第二個(gè)參數(shù)是作為分隔符的字符串。
如果fn:join函數(shù)的第二個(gè)參數(shù)是空字符串,則fn:join函數(shù)的返回值直接將元素連接起來。例如:
假設(shè)stringArray是保存在Web域中的一個(gè)屬性,它表示一個(gè)值為{"www","it315","org"}的字符串?dāng)?shù)組,則fn:join(stringArray,".")返
fn:join(fn:split("www,it315,org",","),".") 的返回值為字符串"
fn:indexOf
fn:indexOf 函數(shù)返回指定字符串在一個(gè)字符串中第一次出現(xiàn)的索引值,返回值為int類型。fn:indexOf函數(shù)接收兩個(gè)字符串類型的參數(shù),如果第一個(gè)參數(shù)字符串中包含第二個(gè)參數(shù)字符串,那么不管第二個(gè)參數(shù)字符串在第一個(gè)參數(shù)字符串中出現(xiàn)幾次,
fn:indexOf函數(shù)總是返回第一次出現(xiàn)的索引值;如果第一個(gè)參數(shù)中不包含第二個(gè)參數(shù),則fn:indexOf函數(shù)返回-1。如果第二個(gè)參數(shù)為空字符串,則fn:indexOf函數(shù)總是返回0。
fn:contains
fn:contains函數(shù)檢測一個(gè)字符串中是否包含指定的字符串,返回值為布爾類型。fn:contains函數(shù)在比較兩個(gè)字符串是否相等時(shí)是大小寫敏感的。
fn:contains函數(shù)接收兩個(gè)字符串類型的參數(shù),如果第一個(gè)字符串中包含第二個(gè)參數(shù)字符串返回true,否則返回false。如果第二個(gè)參數(shù)的值為空字符串,則fn:contains函數(shù)總是返回true。實(shí)際上,fn:contains(string,substring)等價(jià)于fn:indexOf(string,sunstring)!= -1
忽略大小寫的EL函數(shù):fn:containsIgnoreCase
fn:startsWith
fn:startsWith 函數(shù)用于檢測一個(gè)字符串是否以指定的字符串開始的,返回值為布爾類型。
fn:startsWith 函數(shù)接收兩個(gè)字符串類型的參數(shù),如果第一個(gè)參數(shù)字符串以第二個(gè)參數(shù)字符串開始,則函數(shù)返回true,否則函數(shù)返回false。如果第二個(gè)參數(shù)為空字符串,則fn:startsWith函數(shù)總是返回true。例如:
與之對應(yīng)的EL函數(shù):fn:endsWith
fn:replace
fn:replace函數(shù)將一個(gè)字符串中包含的指定字符串替換為其他的指定字符串,并返回替換后的結(jié)果字符串。fn:replace("www it315 org"," ",".")的返回值為字符串"
fn:substring
fn:substring 函數(shù)用于截取一個(gè)字符串的子字符串并返回截取到的子字符串。fn:substring函數(shù)接收三個(gè)參數(shù),第一個(gè)參數(shù)是用于指定要操作的源字符串,第二個(gè)參數(shù)是用于指定截取子字符串開始的索引值,第三個(gè)參數(shù)是用于指定截取子字符串結(jié)束的索引值,第二個(gè)參數(shù)和第三個(gè)參數(shù)都是int類型,其值都從0開始例如:
fn:substringAfter
fn:substringAfter函數(shù)用于截取并返回一個(gè)字符串中的指定字符串第一次出現(xiàn)之后的子字符串。fn:substringAfter函數(shù)接收兩個(gè)字符串類型的參數(shù),第一個(gè)參數(shù)表示要操作的源字符串,第二個(gè)參數(shù)表示指定的子字符串。
與之對應(yīng)的EL函數(shù)為:fn:substringBefore
自定義EL函數(shù)開發(fā)步驟
EL自定義函數(shù)開發(fā)與應(yīng)用包括以下三個(gè)步驟:
編寫一個(gè)Java類,方法必須是靜態(tài)方法。
在WEB-INF目錄下新建一個(gè)tld的文件。
沒有標(biāo)簽的提示,復(fù)制http://java.sun.com/xml/ns/j2ee , 合并名稱
設(shè)置2.0,設(shè)置url和shortname
編寫標(biāo)簽庫描述符(tld)文件,在tld文件配置自定義函數(shù)
使用function標(biāo)簽配置自定義函數(shù)。
使用name標(biāo)簽配置方法名(可以任意)
使用function-class標(biāo)簽配置類的全路徑
使用function-signature 標(biāo)簽配置返回值類型(中間有空格)方法名稱(參數(shù)類型)
在JSP頁面中導(dǎo)入和自定義函數(shù)
開發(fā)EL function注意事項(xiàng)
編寫標(biāo)簽庫描述文件后,需要將它放置到<web應(yīng)用>\WEB-INF目錄中或WEB-INF目錄下的除了classes和lib目錄之外的任意子目錄中。
TLD文件中的<uri>元素用指定該TLD文件的URI,在JSP文件中需要通過這個(gè)URI來引入該標(biāo)簽庫描述文件。
<function>元素用于描述一個(gè)EL自定義函數(shù),其中:
<name>子元素用于指定EL自定義函數(shù)的名稱。
<funtion-class>子元素用于指定完整的Java類名。
<function-signature>子元素用于指定Java類中的靜態(tài)方法的簽名,方法簽名必須指明方法的返回類型以及各個(gè)參數(shù)的類型,
各個(gè)參數(shù)之間用逗號分隔。
實(shí)例如下:
在src下新建一個(gè)cn.itcast.el的包,在包內(nèi)新建ElDemo1.java
代碼如下:
package cn.itcast.el;
public class ElDemo1 {
public static String sayHello(String name){
return "hello "+name;
}
}
在WebRoot/WEB-INF下新建myfn的tld文件 并進(jìn)行配置:

配置后的代碼如下:
<?xml version="1.0" encoding="UTF-8"?> <taglib version="2.0" 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"> <tlib-version>1.0</tlib-version> <short-name>myfn</short-name> <uri>http://www.itcast.cn/1110/myfn</uri> <!-- 配置自定義的EL函數(shù) --> <function> <!-- 配置方法名稱 --> <name>sayHi</name> <!-- 方法所在的類 --> <function-class>cn.itcast.el.ElDemo1</function-class> <!-- 配置方法的簽名 --> <function-signature>java.lang.String sayHello(java.lang.String)</function-signature> </function> </taglib>
在WebRoot根目錄下新建el文件夾,在里面新建demo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="http://www.itcast.cn/1110/myfn" prefix="myfn" %>
<!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>Insert title here</title>
</head>
<body>
${ fn:length("abcdefg") }
${ fn:toUpperCase("abcdefg") }
${ myfn:sayHi("小風(fēng)") }
</body>
</html>

自定義標(biāo)簽
自定義標(biāo)簽簡介
自定義標(biāo)簽主要用于移除JSP頁面中的Java代碼,提高代碼的復(fù)用性
使用自定義標(biāo)簽移除jsp頁面在奇偶那個(gè)的Java代碼,只需要完成以下步驟:
- 編寫一個(gè)實(shí)現(xiàn)Tag接口的Java類(標(biāo)簽處理器)
- 編寫標(biāo)簽庫描述符(tld)文件,在tld文件中對標(biāo)簽處理器類描述成一個(gè)標(biāo)簽
- 參考Tomcat中example項(xiàng)目中的JSP部分
因?yàn)槠髽I(yè)業(yè)務(wù)需求是多種多樣的,所以常見開源框架只能提供通用的Java代碼功能,如果實(shí)現(xiàn)既定業(yè)務(wù)邏輯功能,需要自定義標(biāo)簽。通過自定義標(biāo)簽(簡化復(fù)雜業(yè)務(wù)開發(fā))

簡單標(biāo)簽
由于傳統(tǒng)標(biāo)簽使用三個(gè)標(biāo)簽接口來完成不同的功能,顯得過于繁瑣,不利于標(biāo)簽技術(shù)的推廣,SUN公司為降低標(biāo)簽技術(shù)的學(xué)習(xí)難度,在JSP2.0中定義了一個(gè)更為簡單、便于編寫和調(diào)用的SimpleTag接口來實(shí)現(xiàn)標(biāo)簽的功能。實(shí)現(xiàn)SimpleTag接口的標(biāo)簽通常稱為簡單標(biāo)簽。
SimpleTag方法介紹
- setJspContext方法:用于把JSP頁面的pageContext對象傳遞給標(biāo)簽處理器對象。
- setParent方法:用于把父標(biāo)簽處理器對象傳遞給當(dāng)前標(biāo)簽處理器對象。
- getParent方法:用于獲得當(dāng)前標(biāo)簽的父標(biāo)簽處理對象。
- setJspBody方法:用于把代表標(biāo)簽體的JspFragment對象傳遞給標(biāo)簽處理器對象。即傳入標(biāo)簽體緩存對象(封裝了標(biāo)簽體內(nèi)容)
- doTag方法:用于完后所有標(biāo)簽邏輯,包括輸出、迭代、修改標(biāo)簽體內(nèi)容等。在doTag方法中可以拋出
- javax.servlet.jsp.SkipPageException異常,用于通知WEB容器不再執(zhí)行JSP頁面中位于結(jié)束標(biāo)記后面的內(nèi)容,這等效于在傳統(tǒng)標(biāo)簽的doEndTag方法中返回Tag.SKIP_PAGE常量的情況。
簡單標(biāo)簽庫開發(fā)常用功能,實(shí)現(xiàn)SimpleTag接口標(biāo)簽類(SimpleTag JSP2.0 之后為了簡化標(biāo)簽開發(fā)提供的)
編寫簡單的標(biāo)簽類,只需要繼承SimpleTagSupport類
setJspContext 傳入pageContext對象
setParent 傳入父標(biāo)簽對象
setJSPBody 傳入標(biāo)簽體緩存對象(封裝了標(biāo)簽體內(nèi)容)
doTag (執(zhí)行標(biāo)簽,在該方法中編寫標(biāo)簽代碼邏輯)
在setJSPBody方法中傳入對象JSPFragment,該對象封裝了標(biāo)簽體內(nèi)容,控制標(biāo)簽體內(nèi)容輸出
最重要方法invoke(Writer out) 意義將標(biāo)簽體內(nèi)容輸出到指定字符輸出流中。
注意:在簡單標(biāo)簽庫中<bodyContent>不能寫JSP,而必須寫scriptless
SimpleTag接口方法的執(zhí)行順序:
當(dāng)web容器開始執(zhí)行標(biāo)簽時(shí),會調(diào)用如下方法完成標(biāo)簽的初始化:
- WEB容器調(diào)用標(biāo)簽處理器對象的setJspContext方法,將代表JSP頁面的pageContext對象傳遞給標(biāo)簽處理器對象。
- WEB容器調(diào)用標(biāo)簽處理器對象的setParent方法,將父標(biāo)簽處理器對象傳遞給這個(gè)標(biāo)簽處理器對象。注意,只有在標(biāo)簽存在父標(biāo)簽的情況下,WEB容器才會調(diào)用這個(gè)方法。
- 如果調(diào)用標(biāo)簽時(shí)設(shè)置了屬性,容器將調(diào)用每個(gè)屬性對應(yīng)的setter方法把屬性值傳遞給標(biāo)簽處理器對象。如果標(biāo)簽的屬性值是EL表達(dá)式,則WEB容器首先計(jì)算表達(dá)式的值,然后把值傳遞給標(biāo)簽處理器對象。
- 如果簡單標(biāo)簽有標(biāo)簽體,容器將調(diào)用setJSPBody方法把代表標(biāo)簽體的JspFragment對象傳遞進(jìn)來。
執(zhí)行標(biāo)簽時(shí):
- 容器調(diào)用標(biāo)簽處理器的doTag() 方法,開發(fā)人員在方法內(nèi)通過操作JspFragment對象,就可以實(shí)現(xiàn)是否執(zhí)行、迭代、修改標(biāo)簽體的目的。

JSPFragment類
(1)javax.servlet.jsp.tagext.JspFragment類是在JSP2.0中定義的,它的實(shí)例對象代表JSP頁面中的一段符合JSP語法規(guī)范的JSP片段,這段JSP片段中不能包含JSP腳本元素。
(2)WEB容器在處理簡單標(biāo)簽的標(biāo)簽體時(shí),會把標(biāo)簽體內(nèi)容用一個(gè)JspFragment對象表示,并調(diào)用標(biāo)簽處理器對象的setJSPBody方法把JspFragment對象傳遞給標(biāo)簽處理器對象。JspFragment類中只定義了兩個(gè)方法,如下所示:
getJspContext方法:用于返回代表調(diào)用頁面的JspContext對象——pageContext
public abstract void invoke(java.io.Writer out) 輸出標(biāo)簽內(nèi)容
用于執(zhí)行JspFragment對象所代表的JSP代碼片段
參數(shù)out用于指定將JspFragment對象的執(zhí)行結(jié)果寫入到哪個(gè)輸出流對象中,如果傳遞給參數(shù)out的值為null,則將執(zhí)行結(jié)果寫入到JspContext.getOut()方法返回的輸出流對象中。(簡而言之,可以理解為寫給瀏覽器)
invoke方法詳解
JspFragment.invoke方法是JspFragment最重要的方法,利用這個(gè)方法可以控制是否執(zhí)行和輸出標(biāo)簽體的內(nèi)容、是否迭代執(zhí)行標(biāo)簽體的內(nèi)容或?qū)?biāo)簽體的執(zhí)行結(jié)果進(jìn)行修改后再輸出。例如:
- 在標(biāo)簽處理器中如果沒有調(diào)用JspFragment.invoke方法,其結(jié)果就相當(dāng)于忽略標(biāo)簽體內(nèi)容;
- 在標(biāo)簽體處理器中重復(fù)調(diào)用JspFragment.invoke方法,則標(biāo)簽體內(nèi)容會被重復(fù)執(zhí)行;
- 若想在標(biāo)簽處理器中修改標(biāo)簽體內(nèi)容,只需在調(diào)用invoke方法時(shí)指定一個(gè)可取出結(jié)果數(shù)據(jù)的輸出流對象(例如:StringWriter),讓標(biāo)簽體的執(zhí)行結(jié)果輸出到該輸出流對象中,然后從該輸出流對象中取出數(shù)據(jù)進(jìn)行修改后在輸出到目標(biāo)設(shè)備,即可達(dá)到修改標(biāo)簽體的目的。
例:控制標(biāo)簽后的jsp頁面是否執(zhí)行
doTag
throw new SkipPageException
TLD配置
<tag>
<name>demo2</name>
<tag-class>simple.MyTag2</tag-class>
<body-content>empty</body-content>
</tag>
自定義標(biāo)簽入門
需求:自定義標(biāo)簽<myc:print>在頁面中輸出hello
步驟一:編寫標(biāo)簽類
編寫一個(gè)類,繼承SimpleTagSupport
重寫兩個(gè)方法,doTag()和setJspContext(JspContext pc)
通過JspContext 對象可以獲取out對象向外輸出內(nèi)容
步驟二:提供tld文件進(jìn)行配置
通過<tag>標(biāo)簽配置自定義標(biāo)簽
配置標(biāo)簽名稱<name>print</name>
配置標(biāo)簽的類<tag-class>xxx.xxx.xxx</tag-class>
配置標(biāo)簽體的內(nèi)容<body-content>empty</body-content>
步驟三:在JSP頁面中引入該標(biāo)簽庫
自定義帶有標(biāo)簽體的標(biāo)簽
需求:自定義標(biāo)簽<myc:out>在頁面中輸出內(nèi)容
步驟一:編寫標(biāo)簽類
編寫一個(gè)類,繼承SimpleTagSupport
重寫兩個(gè)方法,doTag()和setJspContext(JspContext pc)
在doTag()中通過getJspBody()獲取JspFragment標(biāo)簽體,調(diào)用invoke(null)
步驟二:提供tld文件進(jìn)行配置
通過<tag>標(biāo)簽配置自定義標(biāo)簽
配置標(biāo)簽名稱<name>out</name>
配置標(biāo)簽的類<tag-class>xxx.xxx.xxx</tag-class>
配置標(biāo)簽體的內(nèi)容<body-content>scriptless</body-content>
步驟三:在JSP的頁面中引入該標(biāo)簽庫
Body-content的配置
<body-content>元素的可選值有:
- empty:不能有標(biāo)簽體內(nèi)容
- JSP:標(biāo)簽體內(nèi)容可以是任何東西:EL、JSTL、<%= %>、<%%>,以及HTML;但不建議使用Java代碼段,SimpleTag已經(jīng)不再支持使用<body-content>JSP</body-content>
- scriptless:標(biāo)簽體內(nèi)容不能是Java代碼段,但可以是EL、JSTL等。
- tagdependent:標(biāo)簽體內(nèi)容不做運(yùn)算,由標(biāo)簽處理類自行處理,無論標(biāo)簽體內(nèi)容是EL、JSP、JSTL,都不會做運(yùn)算。
自定義帶有屬性的標(biāo)簽
需求:自定義標(biāo)簽<myc:if>在頁面中輸出內(nèi)容
步驟一:編寫標(biāo)簽類
編寫一個(gè)類,繼承SimpleTagSupport類。
提供頁面的屬性,設(shè)置成boolean類型。并提供set方法,頁面的屬性與類中的屬性名稱必須相同。
重寫doTag()方法,判斷屬性是否為true,通過getJspBody()獲取JspFragment標(biāo)簽體,調(diào)用invoke(null)
步驟二:提供tld文件進(jìn)行配置
通過<tag>標(biāo)簽配置自定義標(biāo)簽
配置標(biāo)簽名稱<name>if</name>
配置標(biāo)簽的類<tag-class>xxx.xxx.xxx</tag-class>
配置標(biāo)簽體的內(nèi)容<body-content>scriptless</body-content>
配置屬性<attribute>在屬性中配置其他信息</attribute>
步驟三:在JSP頁面中引入標(biāo)簽庫
attribute的配置
(1)配置屬性名稱
<name>test</name>
(2)屬性是否是必須的
<required>true</required>
(3)配置是否支持EL表達(dá)式
<rtexprvalue>true</rtexprvalue>
(4)配置屬性的類型
<type>boolean</type>
在TLD中描述標(biāo)簽屬性attribute
| 元素名 | 是否必須指定 | 描述 |
| description | 否 | 用于指定屬性的描述信息 |
| name | 是 | 用于指定屬性的名稱。屬性名稱是大小寫敏感的,并且不能以jsp、 _jsp、java和sun開頭 |
| required | 否 | 用于指定在JSP頁面中調(diào)用自定義標(biāo)簽時(shí)是否必須設(shè)置這個(gè)屬性。其 取值包括true和false,默認(rèn)值是false,true表示必須設(shè)置,否則可以 設(shè)置也可以不設(shè)置該屬性。 |
| rtexprvalue | 否 | rtexprvalue是runtime expression value(運(yùn)行時(shí)表達(dá)式)的英文簡寫, 用于指定屬性值是一個(gè)靜態(tài)值或動(dòng)態(tài)值。其取值包括true和false,默認(rèn)值 是false,false表示只能為該屬性指定靜態(tài)文本值,例如"123"; true表示可 以為該屬性指定一個(gè)JSP動(dòng)態(tài)元素,動(dòng)態(tài)元素的結(jié)果作為屬性值,例如 JSP表達(dá)式<%=value %> |
| type | 否 | 用于指定屬性值的Java類型。默認(rèn)是String |
<tag>元素的<attribute>子元素用于描述自定義
標(biāo)簽的一個(gè)屬性,自定義標(biāo)簽所具有的每個(gè)屬性
都要對應(yīng)一個(gè)<attribute>元素 。
<attribute> <description>description</description> <name>aaaa</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <type>ObjectType</type> </attribute>
實(shí)例如下:
在WEB項(xiàng)目的src目錄下新建cn.itcast.tag包,在包內(nèi)新建三個(gè)標(biāo)簽實(shí)現(xiàn)類
TagDemo1.java (沒有標(biāo)簽體的自定義標(biāo)簽)
package cn.itcast.tag;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 對外輸出Hello
* @author Administrator
*
*/
public class TagDemo1 extends SimpleTagSupport{
private PageContext pc;
public void doTag() throws JspException, IOException {
pc.getOut().write("Hello");
}
/**
* 服務(wù)器默認(rèn)先執(zhí)行該方法
*/
public void setJspContext(JspContext pc) {
this.pc = (PageContext) pc;
}
}
TagDemo2.java (有標(biāo)簽體 處理標(biāo)簽體內(nèi)容)
package cn.itcast.tag;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 帶有標(biāo)簽主體
* @author Administrator
*
*/
public class TagDemo2 extends SimpleTagSupport{
private PageContext pc;
public void doTag() throws JspException, IOException {
JspFragment jf = getJspBody();
StringWriter sw = new StringWriter();
//通過invoke方法將標(biāo)簽體內(nèi)容寫入到參數(shù)Writer對象sw中
jf.invoke(sw);
// 獲取標(biāo)簽體內(nèi)容
String content = sw.toString().toUpperCase();
pc.getOut().print(content);
}
public void setJspContext(JspContext pc) {
this.pc = (PageContext)pc;
}
}
TagDemo3.java (有屬性 有標(biāo)簽體的自定義標(biāo)簽)
package cn.itcast.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 類似<c:if>標(biāo)簽,帶有屬性的
* @author Administrator
*
*/
public class TagDemo3 extends SimpleTagSupport{
private boolean test;
public void setTest(boolean test) {
this.test = test;
}
public void doTag() throws JspException, IOException {
if(test){
getJspBody().invoke(null);
}
}
}
在WebRoot/WEB-INF 目錄下新建myc.tld文件
配置內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" 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">
<tlib-version>1.0</tlib-version>
<short-name>myc</short-name>
<uri>http://www.itcast.cn/1110/myc</uri>
<!-- 配置自定義標(biāo)簽 -->
<tag>
<!-- 配置標(biāo)簽名稱 -->
<name>print</name>
<!-- 配置標(biāo)簽的類 -->
<tag-class>cn.itcast.tag.TagDemo1</tag-class>
<!-- 配置標(biāo)簽主體 -->
<body-content>empty</body-content>
</tag>
<!-- 配置自定義標(biāo)簽 -->
<tag>
<!-- 配置標(biāo)簽名稱 -->
<name>out</name>
<!-- 配置標(biāo)簽的類 -->
<tag-class>cn.itcast.tag.TagDemo2</tag-class>
<!-- 配置標(biāo)簽主體 -->
<body-content>scriptless</body-content>
</tag>
<!-- 配置自定義標(biāo)簽 -->
<tag>
<!-- 配置標(biāo)簽名稱 -->
<name>if</name>
<!-- 配置標(biāo)簽的類 -->
<tag-class>cn.itcast.tag.TagDemo3</tag-class>
<!-- 配置標(biāo)簽主體 -->
<body-content>scriptless</body-content>
<!-- 配置屬性 -->
<attribute>
<!-- 配置屬性名稱 -->
<name>test</name>
<!-- 屬性是否是必須的 -->
<required>true</required>
<!-- 是否支持EL表達(dá)式 -->
<rtexprvalue>true</rtexprvalue>
<!-- 屬性的類型 -->
<type>boolean</type>
</attribute>
</tag>
</taglib>
在WebRoot下新建tag文件夾,新建tag.jsp 測試自定義標(biāo)簽內(nèi)容
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.itcast.cn/1110/myc" prefix="myc" %>
<%@ 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>Insert title here</title>
</head>
<body>
<myc:print/>
<myc:out>
liuxun1993
</myc:out>
<c:set var="i" value="10"></c:set>
<myc:if test="${ i eq 10 }">
美美
</myc:if>
</body>
</html>
啟動(dòng)服務(wù)器,運(yùn)行結(jié)果如下:

以上所述是小編給大家介紹的JavaWeb開發(fā)之JSTL標(biāo)簽庫的使用、 自定義EL函數(shù)、自定義標(biāo)簽(帶屬性的、帶標(biāo)簽體的),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
spring/springboot整合curator遇到的坑及解決
這篇文章主要介紹了spring/springboot整合curator遇到的坑及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
詳解Kotlin和anko融合進(jìn)行Android開發(fā)
本篇文章主要介紹了Kotlin和anko融合進(jìn)行Android開發(fā),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11
springboot?通過博途獲取plc點(diǎn)位的數(shù)據(jù)代碼實(shí)現(xiàn)
這篇文章主要介紹了springboot?通過博途獲取plc點(diǎn)位的數(shù)據(jù)的代碼實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
Netty分布式NioSocketChannel注冊到selector方法解析
這篇文章主要為大家介紹了Netty分布式源碼分析NioSocketChannel注冊到selector方法的解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
Java通過python命令執(zhí)行DataX任務(wù)的實(shí)例
今天小編就為大家分享一篇Java通過python命令執(zhí)行DataX任務(wù)的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
SpringBoot自動(dòng)裝配之Condition深入講解
@Conditional表示僅當(dāng)所有指定條件都匹配時(shí),組件才有資格注冊。該@Conditional注釋可以在以下任一方式使用:作為任何@Bean方法的方法級注釋、作為任何類的直接或間接注釋的類型級別注釋@Component,包括@Configuration類、作為元注釋,目的是組成自定義構(gòu)造型注釋2023-01-01
深入理解@component與@Configuration注解
這篇文章主要介紹了深入理解@component與@Configuration注解,從Spring3.0,@Configuration用于定義配置類,可替換xml配置文件,被注解的類內(nèi)部包含有一個(gè)或多個(gè)被@Bean注解的方法,這些方法將會被掃描,并用于構(gòu)建bean定義,初始化Spring容器,需要的朋友可以參考下2023-11-11
Java 如何實(shí)現(xiàn)照片轉(zhuǎn)化為回憶中的照片
本文主要介紹了可以對圖片進(jìn)行色彩處理的Java工具類,讓圖片變成回憶中的畫面,主要將圖片做黑白與褐色的處理。代碼具有一定價(jià)值,感興趣的童鞋可以關(guān)注一下2021-11-11

