JSTL優點:在於EL和標準動做沒法達到目的,又不使用腳本代碼。(JSTL 1.1不是JSP2.0規範的一部分,TOMCAT高版本已經自帶了JSTL的JAR包)php
使用JSTL須要使用指令,引入JSTLhtml
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
JSTL核心標籤庫包含了一組用於實現WEB應用中的通用操做的標籤,JSP規範爲核心標籤庫建議的前綴名爲c。java
<c:out> 標籤用於輸出一段文本內容到pageContext對象當前保存的「out」對象中,在一般狀況下,pageContext對象當前保存的「out」對象的數據是輸出到客戶端瀏覽器,因此,<c:out> 標籤一般用於輸出一段文本內容到客戶端瀏覽器。若是<c:out> 標籤輸出的文本內容中包含了須要進行轉義的HTML特殊字符,例如,<、>、'、"、&等,<c:out> 標籤默認對它們按表8.2進行HTML編碼轉換後再進行輸出,這樣就能夠在瀏覽器中顯示出這些字符。spring
表8.2 特殊字符轉換sql
<c:out>標籤標籤有兩種語法格式:數據庫
語法1,沒有標籤體的狀況:api
<c:out value="value" 數組
[escapeXml="{true|false}"]瀏覽器
[default="defaultValue"] />服務器
語法2,有標籤體的狀況,在標籤體中指定輸出的默認值:
<c:out value="value"
[escapeXml="{true|false}"] >
default value
</c:out>
<c:out>標籤的屬性說明如表8.3所示。
表8.3 <c:out>標籤的屬性
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
value |
true |
Object |
指定要輸出的內容 |
escapeXml |
true |
Boolean |
指定是否將>、<、&、'、" 等特殊字符進行HTML編碼轉換後再進行輸出。默認值爲true |
default |
true |
Object |
指定若是value屬性的值爲null時所輸出的默認值 |
當且僅當value屬性的值爲null時,<c:out> 標籤輸出默認值;若是沒有指定默認值,默認爲空字符串。<c:out> 標籤的標籤體的內容用於指定輸出的默認值,若是value屬性的值不爲null,即便標籤體部分不爲空,標籤體的內容也不會被輸出。若是value屬性不是指向一個java.io.Reader對象,<c:out> 標籤將調用這個對象的toString方法,而後輸出得到的字符串內容。若是value屬性指向一個java.io.Reader對象,<c:out> 標籤將從這個Reader對象中讀取數據後進行輸出,當有大量數據要被輸出時,將這些數據以Reader對象的形式提供給<c:out>標籤進行輸出,將會極大提升系統性能。當採用escapeXml屬性的默認設置值true時,<c:out>標籤將對要輸出的特殊字符按表8.2進行轉換;若是將escapeXml屬性設置爲false,<c:out>標籤將不對要輸出的特殊字符進行轉換,而是直接輸出這些特殊字符。
例程8-3是<c:out> 標籤的一個演示例子程序。
例程8-3 c_out1.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%
session.setAttribute("test_session", "testValue_session");
%>
直接輸出一個字符串:
<c:out value="test" default="123456" /><br /><hr />
輸出Web域中不存在的屬性的值:<br />
<c:out value="${test_request}" default="這個屬性不存在"/><br /><hr />
輸出Web域中的test_session屬性的值:<br />
<c:out value="${test_session}" />
例程8-3的運行結果如圖8.1所示。
圖8.1
例程8-4和例程8-5是兩個用於演示<c:out>標籤的escapeXml屬性的例子程序,例程8-4沒有設置escapeXml屬性,例程8-5將escapeXml屬性設置爲了false。
例程8-4 c_out2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out value="${null}" >
<meta http-equiv="refresh" content="0;url=http://www.it315.org" />
</c:out>
例程8-5 c_out3.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out value="${null}" escapeXml="false">
<meta http-equiv="refresh" content="0;url=http://www.it315.org" />
</c:out>
例程8-4和例程8-5的運行結果分別如圖8.2和圖8.3所示。
圖8.2
圖8.3
<c:set>標籤用於設置各類Web域中的屬性,或者設置Web域中的java.util.Map類型的屬性對象或JavaBean類型的屬性對象的屬性。<c:set>標籤有四種語法格式:
語法1,使用value屬性設置指定域中的某個屬性的值:
<c:set value="value"
var="varName"
[scope="{page|request|session|application}"] />
語法2,在標籤體中設置指定域中的某個屬性的值:
<c:set var="varName"
[scope="{page|request|session|application}"]>
body content
</c:set>
語法3,使用value屬性設置Web域中的一個屬性對象的某個屬性:
<c:set value="value"
target="target"
property="propertyName" />
語法4,在標籤體中設置Web域中的一個屬性對象的某個屬性性:
<c:set target="target"
property="propertyName">
body content
</c:set>
<c:set>標籤的屬性說明如表8.4所示。
表8.4 <c:set>標籤的屬性
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
value |
true |
Object |
用於指定屬性值 |
var |
false |
String |
用於指定要設置的Web域屬性的名稱 |
scope |
false |
String |
用於指定屬性所在的Web域 |
target |
true |
Object |
用於指定要設置屬性的對象,這個對象必須是JavaBean對象或java.util.Map對象 |
property |
true |
string |
用於指定當前要爲對象設置的屬性名稱 |
若是使用第1種語法格式時的value屬性值爲null,或者使用第2種語法格式時的標籤體內容爲空,<c:set>標籤將從scope屬性指定的域範圍中刪除var屬性指定的屬性。
在第3種語法格式和第4語法格式中,若是target屬性的值是java.util.Map對象,property屬性表示該Map對象的關鍵字,若是Map對象沒有指定的關鍵字,就給Map對象增長指定的關鍵字;若是target屬性的值是JavaBean對象,property屬性表示JavaBean對象的屬性,若是value的類型與JavaBean屬性的類型不匹配時,會根據EL的轉換規則自動進行轉換。當使用第3種語法格式或第4種語法格式時,若是target屬性的值爲null(即target屬性指定的對象不存在),或者target屬性的值是一個JavaBean對象,但該JavaBean中不存在property屬性指定的屬性,<c:set>標籤將拋出異常。若是使用第3種語法格式時value屬性的值爲null,或者使用第4種語法格式時標籤體的內容爲空,若是target屬性的值是一個java.util.Map對象,就從Map對象中刪除property屬性指定的關鍵字對應的項;若是target屬性的值是一個JavaBean對象,就將JavaBean的相應屬性的值設置爲null。
例程8-6是使用<c:set>標籤設置某個Web域中的屬性的一個演示例子程序。
例程8-6 c_set1.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:set var="userName" scope="session">
zxx
</c:set>
輸出session 做用域中的userNamer屬性的值:
<c:out value="${userName}" /><br /><hr />
輸出session 做用域中的bookname屬性的值:
<c:set var="bookname" scope="session" />
<c:out value="${bookname}" />
例程8-6的運行結果如圖8.4所示。
圖8.4
例程8-7是使用<c:set>標籤設置UserBean對象和Map對象的屬性的一個演示例子程序。
例程8-7 c_set2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.HashMap" %>
<jsp:useBean id="user" class="org.it315.UserBean" />
<%
HashMap preferences = new HashMap();
session.setAttribute("preferences",preferences);
%>
設置和輸出UserBean對象的userName屬性值:
<c:set value="zxx" target="${user}" property="userName" />
<c:out value="${user.userName}" /><br /><hr />
設置和輸出UserBean對象的password屬性值:
<c:set target="${user}" property="password" />
<c:out value="${user.password}" /><br /><hr />
設置和輸出Map對象的color關鍵字的值:
<c:set target="${preferences}" property="color" value="${param.color}" />
<c:out value="${preferences.color}" />
在瀏覽器地址欄輸入以下地址訪問例程8-7:
http://localhost:8080/JSTL/c_set2.jsp?color=green
例程8-7的運行結果如圖8.5所示。
圖8.5
<c:remove>標籤用於刪除各類Web域中的屬性,其語法格式以下:
<c:remove var="varName"
[scope="{page|request|session|application}"] />
var屬性用於指定要刪除的屬性的名稱,scope屬性用於指定要刪除的屬性所屬的Web域,它們的值都不能接受動態值。若是沒有指定scope屬性,<c:remove>標籤就調用PageContext.removeAttribute(varName)方法,不然就調用PageContext.removeAttribute(varName, scope) 方法。<c:remove>與<c:set>標籤第一種語法格式的value屬性值爲null時的做用相同。
例程8-8是使用<c:remove>標籤的一個演示例子程序。
例程8-8 c_remove.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:set value="org.it315" var="company" scope="request" />
<c:set var="passWord" scope="session">
a123456a
</c:set>
在沒有使用 <c:remove> 標籤以前,變量的值爲:<br />
company:<c:out value="${company}" /><br />
passWord:<c:out value="${passWord}" /><br />
<c:remove var="company" scope="request" />
<!--c:set var="company" scope="request" 此行與黑體字的一行做用是同樣的/-->
<c:remove var="passWord" scope="session" /><hr />
在使用 <c:remove> 標籤以後,變量的值爲:<br />
company:<c:out value="${company}" /><br />
passWord:<c:out value="${passWord}" />
例程8-8的運行結果如圖8.6所示。
圖8.6
<c:catch>標籤用於捕獲嵌套在標籤體中的內容拋出的異常,其語法格式以下:
<c:catch [var="varName"]>
nested actions
</c:catch>
var屬性用於標識<c:catch>標籤捕獲的異常對象,其值是一個靜態的字符串,不支持動態屬性值。<c:catch>標籤將捕獲的異常對象以var指定的名稱保存到page這個Web域中,若是沒有指定var屬性,則<c:catch>標籤僅捕獲異常,不在page域保存異常對象。若是<c:catch>標籤體中的內容沒有拋出異常,<c:catch>標籤將從page域中刪除var屬性指定的屬性。
<c:catch>標籤能夠捕獲任何標籤拋出的異常,而且能夠同時處理多個標籤拋出的異常,這樣,能夠對JSP頁面的異常進行統一處理,顯示給用戶一個更友好的頁面。JSP處理異常的通用機制是出現重要異常後跳轉到錯誤處理頁面,建議儘可能不要用<c:catch>標籤來代替JSP的錯誤處理機制,只對一些次要異常才使用<c:catch>標籤進行捕獲處理。
例程8-9是使用<c:catch>標籤進行異常捕獲處理的一個演示例子程序。
例程8-9 c_catch.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:catch var="myex">
<%
int i = 0;
int j = 10;
out.println(j + "/" + i + "=" + j/i);
%>
</c:catch>
異常:<c:out value="${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}" />
在例程8-9中,<c:catch>標籤內嵌套的腳本元素拋出了異常,<c:catch var="myex">將捕獲到這個異常,調用<c:out value="${myex.message}" />,至關於調用<%=myex.getMessage()%>。例程8-9的運行結果如圖8.7所示。
圖8.7
JSP頁面的顯示邏輯中也常常須要進行條件判斷,<c:if>標籤能夠構造簡單的「if-then」結構的條件表達式,若是條件表達式的結果爲真就執行標籤體部分的內容。<c:if>標籤有兩種語法格式:
語法1,沒有標籤體的狀況:
<c:if test="testCondition" var="varName"
[scope="{page|request|session|application}"] />
語法2,有標籤體的狀況,在標籤體中指定要執行的內容:
<c:if test="testCondition" [var="varName"]
[scope="{page|request|session|application}"]>
body content
</c:if>
<c:if>標籤的屬性說明如表8.5所示。
表8.5 <c:if>標籤的屬性
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
test |
true |
boolean |
決定是否處理標籤體中的內容的條件表達式 |
var |
false |
String |
用於指定將test屬性的執行結果保存到某個Web域中的某個屬性的名稱 |
scope |
false |
String |
指定將test屬性的執行結果保存到哪一個Web域中 |
對於語法2,若是指定了<c:if>標籤的scope屬性,則必須指定var屬性。
例程8-10是使用<c:if>標籤的一個演示例子程序。
例程8-10 c_if.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<jsp:useBean id="user" class="org.it315.UserBean" />
<c:set value="${param.count}" target="${user}" property="visitCount" />
<c:if test="${user.visitCount == 1}">
這是您第一次訪問本網站,歡迎您!
</c:if>
在瀏覽器地址欄輸入以下地址訪問例程8-10:
http://localhost:8080/JSTL/c_if.jsp?count=1
例程8-10的運行結果如圖8.8所示。
圖8.8
<c:choose>標籤用於指定多個條件選擇的組合邊界,它必須與<c:when>和<c:otherwise>標籤一塊兒使用。使用<c:choose>,<c:when>和<c:otherwise>三個標籤,能夠構造相似 「if-else if-else」 的複雜條件判斷結構。
<c:choose>標籤沒有屬性,在它的標籤體內只能嵌套一個或多個<c:when>標籤和0個或一個<c:otherwise>標籤,而且同一個<c:choose>標籤中的全部<c:when>子標籤必須出如今<c:otherwise>子標籤以前。若是<c:choose>標籤內嵌套一個<c:when>標籤和<c:otherwise>標籤,就至關於「if-else」的條件判斷結構;若是<c:choose>標籤內嵌套多個<c:when>標籤和一個<c:otherwise>標籤,就至關於「if-else if-else」標籤。
<c:when>標籤只有一個test屬性,該屬性的值爲布爾類型。test屬性支持動態值,其值能夠是一個條件表達式,若是條件表達式的值爲true,就執行這個<c:when>標籤體的內容。<c:when>標籤體的內容能夠是任意的JSP代碼。<c:otherwise>標籤沒有屬性,它必須做爲<c:choose>標籤的最後分支出現。
當JSP頁面中使用<c:choose>標籤時,嵌套在<c:choose>標籤內的test條件成立的第一個<c:when>標籤的標籤體內容將被執行和輸出。當且僅當全部的<c:when>標籤的test條件都不成立時,才執行和輸出<c:otherwise>標籤的標籤體內容。若是全部的<c:when>標籤的test條件都不成立,而且<c:choose>標籤內沒有嵌套<c:otherwise>標籤,則不執行任何操做。
例程8-11是使用<c:choose>、<c:when>、<c:otherwise>標籤的一個演示例子程序。
例程8-11 c_choose.jsp
<%@ 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>
在瀏覽器地址欄輸入以下地址訪問例程8-11:
http://localhost:8080/JSTL/c_choose.jsp?count=0
例程8-11的運行結果如圖8.9所示。若是將參數count的值修改成10,則運行結果如圖8.10所示。
圖8.9
圖8.10
例程8-12是一個綜合使用<c:if>標籤和<c:choose>等標籤的例子程序,在這個例子程序中,首先使用<c:if>標籤判斷表單提交的方式是不是POST,若是是,就再使用<c:choose>等標籤根據表單提交的內容進行不一樣的處理。
例程8-12 c_customLogic.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${pageContext.request.method=='POST'}">
<c:choose>
<c:when test="${param.favor == 'computer'}">
Your favourite course is <b>computer</b>.
</c:when>
<c:otherwise>
Your favourite course is <i>other</i>.
</c:otherwise>
</c:choose>
</c:if>
<form method="POST">What is your favourite course?<br/>
<input type="text" name="favor" />
<input type="submit" value="submit" />
</form>
在瀏覽器地址欄中直接訪問c_customLogic.jsp的運行結果如圖8.11所示,在文本框中輸入「computer」,單擊其中的submit按鈕後的運行結果如圖8.12所示。
圖8.11
圖8.12
JSP頁面的顯示邏輯中也常常須要對集合對象進行循環迭代操做,<c:forEach>標籤用於對一個集合對象中的元素進行循環迭代操做,或者按指定的次數重複迭代執行標籤體中的內容。<c:forEach>標籤有兩種語法格式:
語法1,在集合對象中迭代:
<c:forEach [var="varName"]
items="collection"
[varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
語法2,迭代固定的次數:
<c:forEach [var="varName"]
[varStatus="varStatusName"]
begin="begin" end="end" [step="step"]>
body content
</c:forEach>
<c:forEach>標籤的屬性說明如表8.6所示。
表8.6 <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:forEach>標籤時,須要注意以下幾點說明:
l 若是指定begin屬性,其值必須大於或等於零;
l 若是指定步長(step屬性),其值必須大於或等於1;
l 若是items屬性的值爲null,則要處理的集合對象爲空,這時不執行迭代操做;
l 若是指定的begin屬性的值大於或等於集合對象的長度,不執行迭代操做;
l 若是指定的end屬性的值小於begin屬性的值,不執行迭代操做;
<c:forEach>標籤的items屬性的值支持下面的數據類型:
l 任意類型的數組
l java.util.Collection
l java.util.Iterator
l java.util.Enumeration
l java.util.Map
l String
items屬性還支持與數據庫有關的數據類型java.sql.ResultSet(包括javax.sql.RowSet),這些數據類型將在8.5 節的數據庫標籤中進行介紹。對字符串的迭代操做一般使用<c:forTokens>標籤或JSTL函數,例如fn:split和fn:jion,JSTL函數將在8.7節進行介紹。
1.迭代Collection類型的集合對象
例程8-13是使用<c:forEach>標籤迭代Collection類型的集合對象的一個應用舉例。
例程8-13 c_forEach_collection.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.*,org.it315.UserBean" %>
<%
Collection users = new ArrayList();
for(int i=0; i<5; i++)
{
UserBean user = new UserBean();
user.setUserName("user" + i);
user.setPassword("guess" + i);
users.add(user);
}
session.setAttribute("users", users);
%>
<div style="text-align:center">User List
<table border="1">
<tr><td>用戶名</td><td>密碼</td></tr>
<c:forEach var="user" items="${users}">
<tr>
<td>${user.userName}</td><td>${user.password}</td>
</tr>
</c:forEach>
</table></div>
例程8-13的運行結果如圖8.13所示。
圖8.13
2.迭代Map對象
使用<c:forEach>標籤迭代Map類型的集合對象時,迭代出的每一個元素的類型爲Map.Entry,Map.Entry表明Map集合中的一個條目項,其中的getKey()方法可得到條目項的關鍵字,getValue()方法可得到條目項的值。
EL中的requestScope隱含對象表明request做用域中的全部屬性的Map對象,因此咱們可使用<c:forEach>標籤迭代輸出EL中的requestScope隱含對象中的全部元素,如例程8-14所示。
例程8-14 c_forEach_map.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%
request.setAttribute("attr1","value1");
request.setAttribute("attr2","value2");
%>
<div style="text-align:center">Properties(Map)
<table border="1">
<tr><td>Map的關鍵字</td><td>Map的對應關鍵字的值</td></tr>
<c:forEach var="entry" items="${requestScope}">
<tr><td>${entry.key}</td><td>${entry.value}</td></tr>
</c:forEach>
</table></div>
例程8-14的運行結果如圖8.14所示。
圖8.14
3.迭代指定的次數
<c:forEach>標籤能夠按指定的次數重複迭代執行標籤體中的內容,使用這種方式迭代時,能夠指定迭代的步長。例程8-15中分別演示了指定迭代步長和沒有指定迭代步長的狀況。
例程8-15 c_forEach_count.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
從11到16迭代,指定迭代步長爲2:
<c:forEach var="i" begin="11" end="16" step="2">
${i}
</c:forEach><br /><hr />
從0到5迭代,沒有指定迭代步長:
<c:forEach var="i" begin="0" end="5">
${i}
</c:forEach>
例程8-15的運行結果如圖8.15所示。
圖8.15
4.指定迭代集合對象的範圍和步長
<c:forEach>標籤迭代集合類對象時,也能夠指定迭代的範圍和步長,如例程8-16所示。
例程8-16 c_forEach_col.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.*,org.it315.UserBean" %>
<%
Collection users = new ArrayList();
for(int i=0; i<6; i++)
{
UserBean user = new UserBean();
user.setUserName("user" + i);
user.setPassword("guest" + i);
users.add(user);
}
session.setAttribute("users", users);
%>
<div style="text-align:center">User List(指定迭代範圍和步長)
<table border="1">
<tr><td>用戶名</td><td>密碼</td></tr>
<c:forEach var="user" items="${users}" end="5" step="2">
<tr>
<td>${user.userName}</td><td>${user.password}</td>
</tr>
</c:forEach>
</table></div>
例程8-16的運行結果如圖8.16所示。
圖8.16
5.獲取迭代的狀態信息
不論是迭代集合對象,仍是迭代指定的次數,在迭代時均可以得到當前的迭代狀態信息。<c:forEach>標籤能夠將表明當前迭代狀態信息的對象保存到page域中,varStatus屬性指定了這個對象保存在page域中的屬性名稱。表明當前迭代狀態信息的對象的類型爲javax.servlet.jsp.jstl.core.LoopTagStatus,從JSTL規範中能夠查看到這個類的詳細信息,其中定義了以下一些方法:
l public java.lang.Integer getBegin()
返回爲標籤設置的begin屬性的值,若是沒有設置begin屬性則返回null
l public int getCount()
返回當前已循環迭代的次數
l public java.lang.Object getCurrent()
返回當前迭代到的元素對象
l public java.lang.Integer getEnd()
返回爲標籤設置的end屬性的值,若是沒有設置end屬性則返回null
l public int getIndex()
返回當前迭代的索引號
l public java.lang.Integer getStep()
返回爲標籤設置的step屬性的值,若是沒有設置step屬性則返回null
l public boolean isFirst()
返回當前是不是第一次迭代操做
l public boolean isLast()
返回當前是不是最後一次迭代操做
例程8-17是一個獲取迭代狀態信息的例子程序。
例程8-17 c_forEach_col2.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%@ page import="java.util.*,org.it315.UserBean" %>
<%
Collection users = new ArrayList();
for(int i=0; i<6; i++)
{
UserBean user = new UserBean();
user.setUserName("user" + i);
user.setPassword("guest" + i);
users.add(user);
}
session.setAttribute("users", users);
%>
<div style="text-align:center">User List
<table border="1">
<tr><td>用戶名</td><td>密碼</td><td>index</td>
<td>count</td><td>first?</td><td>last?</td></tr>
<c:forEach var="user" items="${users}" varStatus="sta" begin="1" step="2">
<tr>
<td>${user.userName}</td><td>${user.password}</td>
<td>${sta.index}</td><td>${sta.count}</td>
<td>${sta.first}</td><td>${sta.last}</td>
</tr>
</c:forEach>
</table></div><hr>
<div style="text-align:center">迭代固定的次數
<table border="1">
<tr><td>數值</td><td>index</td><td>count</td>
<td>first?</td><td>last?</td></tr>
<c:forEach var="i" varStatus="sta1" begin="101" end="103">
<tr>
<td>${i}</td><td>${sta1.index}</td><td>${sta1.count}</td>
<td>${sta1.first}</td><td>${sta1.last}</td>
</tr>
</c:forEach>
</table></div>
例程8-17的運行結果如圖8-17所示。
圖8.17
6.與條件標籤結合使用
迭代標籤能夠與條件標籤結合使用,對數據進行有條件的迭代,應用舉例如例程8-18所示。
例程8-18 c_forEach_com.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<div style="text-align:center">
<table border="1"><tr><td>number</td><td>count</td><td>even|odd</td></tr>
<c:forEach var="i" begin="11" end="13" varStatus="status">
<tr><td>${i}</td><td>${status.count}</td><td>
<c:choose>
<c:when test="${status.count % 2 == 0}">
偶數行
</c:when>
<c:otherwise>
奇數行
</c:otherwise>
</c:choose></td></tr>
</c:forEach>
<table></div>
例程8-18的運行結果如圖8.18所示。
圖8.18
<c:forTokens>標籤專門用於實現相似java.util.StringTokenizer類的迭代功能,但它是以單個字符做爲分隔符,同時能夠指定多個字符做爲多個並行的分隔符。<c:forTokens>標籤的語法格式以下:
<c:forTokens items="stringOfTokens" delims="delimiters"
[var="varName"]
[varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forTokens>
<c:forTokens>標籤的屬性說明如表8.7所示。
表8.7 c:forTokens
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
var |
false |
String |
指定將當前迭代出的子字符串保存到page這個Web域中的屬性名稱 |
items |
true |
String |
將要迭代的字符串 |
delims |
true |
String |
指定一個或多個分隔符 |
varStatus |
false |
String |
指定將表明當前迭代狀態信息的對象保存到page這個Web域中的屬性名稱,表明當前迭代的狀態信息的對象的類型爲javax.servlet.jsp.jstl.core.LoopTagStatus,從JSTL規範中能夠查看這個類的詳細信息 |
begin |
true |
int |
指定從第begin個子字符串開始進行迭代,begin的索引值從0開始編號 |
end |
true |
int |
指定迭代到第begin個子字符串,begin的索引值從0開始編號 |
step |
true |
int |
指定迭代的步長,即每次迭代後的迭代因子增量 |
在使用<c:forTokens>標籤時,須要注意以下幾點說明:
l 若是指定begin屬性,其值必須大於或等於零。
l 若是指定步長(step屬性),其值必須大於或等於1。
l 若是指定的end屬性的值小於begin屬性的值,不執行迭代操做。
例程8-19是一個使用<c:forTokens>標籤的例子程序。
例程8-19 c_forTokens.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
使用"|"做爲分隔符<br />
<c:forTokens var="token" items="spring,summer|autumn,winter" delims="|">
${token}©
</c:forTokens><br />
使用"|"和","做爲分隔符<br />
<c:forTokens var="token" items="spring,summer|autumn,winter" delims="|," end="3">
${token}©
</c:forTokens><br />
使用"-"做爲分隔符<br />
<c:forTokens var="token" items="year--season--month-week" delims="-">
${token}©
</c:forTokens>
例程8-19的運行結果如圖8.19 所示。
圖8.19
JSTL核心標籤庫中提供了以下一些與URL操做相關的標籤:
l <c:import>
l <c:url>
l <c:redirect>
l <c:param>
在舉例講解上面的某些標籤時,要引用另一個JSP文件,這裏先建立好這個JSP文件,如例程8-20所示。
例程8-20 register.jsp
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ page contentType="text/html;charset=gb2312" %>
<%
String name = request.getParameter("name");
name = new String(name.getBytes("iso-8859-1"),"gb2312");
session.setAttribute("name",name);
String country = request.getParameter("country");
country = new String(country.getBytes("iso-8859-1"),"gb2312");
session.setAttribute("country",country);
%>
name=${name};
在JSP頁面進行URL的相關操做時,常常要在URL地址後面附加一些參數。<c:param>標籤能夠嵌套在<c:import>、<c:url>或<c:redirect>標籤內,爲這些標籤所使用的URL地址附加參數。<c:param>標籤在爲一個URL地址附加參數時,將自動對參數值進行URL編碼,例如,若是傳遞的參數值爲「中國」,則將其轉換爲「%d6%d0%b9%fa」後再附加到URL地址後面,這也就是使用<c:param>標籤的最大好處。<c:param>標籤有兩種語法格式:
語法1,使用value屬性指定參數的值:
<c:param name="name" value="value" />
語法2,在標籤體中指定參數的值:
<c:param name="name">
parameter value
</c:param>
<c:param>標籤的屬性說明如表8.8所示。
表8.8 <c:param>標籤的屬性
<c:url>標籤用於在JSP頁面中構造一個URL地址,其主要目的是實現URL重寫。URL重寫就是將會話標識號以參數形式附加在URL地址後面,詳細細節請參看筆者編著的《深刻體驗java Web開發內幕——核心基礎》一書中的第7.4.8的講解。<c:url>標籤有兩種語法格式:
語法1,沒有標籤體的狀況:
<c:url value="value"
[context="context"]
[var="varName"]
[scope="{page|request|session|application}"] />
語法2,有標籤體的狀況,在標籤體中指定構造的URL的參數:
<c:url value="value"
[context="context"]
[var="varName"]
[scope="{page|request|session|application}"]>
<c:param>標籤
</c:url>
<c:url>標籤的屬性說明如表8.9所示。
表8.9 <c:url>標籤的屬性
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
value |
true |
String |
指定要構造的URL |
context |
true |
String |
當要使用相對路徑導入同一個服務器下的其餘WEB應用程序中的URL地址時,context屬性指定其餘WEB應用程序的名稱 |
var |
false |
String |
指定將構造出的URL結果保存到Web域中的屬性名稱 |
scope |
false |
String |
指定將構造出的URL結果保存到哪一個Web域中 |
value屬性所指定的URL能夠是相對路徑和絕對路徑,其具體細節與8.3.12節的<c:import>標籤的url屬性的細節相同。使用<c:url>標籤構造URL時,能夠經過嵌套的<c:param>標籤指定參數,或在value屬性中直接指定參數。
例程8-21是一個使用<c:url>標籤的例子程序。
例程8-21 c_url.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
使用絕對路徑構造URL:
<c:url value="http://localhost:8080/JSTL/URL/register.jsp" var="myUrl1">
<c:param name="name" value="張三" />
<c:param name="country" value="${param.country}" />
</c:url>
<a href="${myUrl1}">Register1</a><hr />
使用相對當前JSP頁面的路徑構造URL:
<c:url value="register.jsp?name=wangwu&country=France" var="myUrl2" />
<a href="${myUrl2}">Register2</a><hr />
使用相對當前WEB應用的路徑構造URL:
<c:url value="/URL/register.jsp?name=zhaoliu&country=England" var="myUrl3" />
<a href="${myUrl3}">Register3</a>
在瀏覽器地址欄輸入以下地址訪問例程8-21:
http://localhost:8080/JSTL/c_url.jsp?country=China
查看例程8-21的運行結果的源文件,內容如例程8-22所示。
例程8-22 c_url.jsp運行結果的源文件
使用絕對路徑構造URL:
<a href="http://localhost:8080/JSTL/URL/register.jsp?name=%d5%c5%c8%fd&country=China">Register1</a><hr />
使用相對當前JSP頁面的路徑構造URL:
<a href="register.jsp?name=wangwu&country=France">Register2</a><hr />
使用相對當前WEB應用的路徑構造URL:
<a href="/JSTL/URL/register.jsp?name=zhaoliu&country=England">Register3</a>
<c:import>標籤用於在JSP頁面中導入一個URL地址指向的資源內容,其做用有點相似<jsp:include>這個JSP標準標籤,但功能更強大。<c:import>標籤標籤有兩種語法格式:
語法1,將URL地址指向的資源內容以字符串形式輸出或以字符串形式保存到一個變量中:
<c:import url="url"
[context="context"]
[var="varName"]
[scope="{page|request|session|application}"]
[charEncoding="charEncoding"]>
optional body content for <c:param> subtags
</c:import>
語法2,將URL地址指向的資源內容保存到一個Reader對象中:
<c:import url="url"
[context="context"]
varReader="varReaderName"
[charEncoding="charEncoding"]>
body content where varReader is consumed by another action
</c:import>
<c:import>標籤的屬性說明如表8.10所示。
表8.10 <c:import>標籤的屬性
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
url |
true |
String |
指定要導入的資源的URL地址 |
context |
true |
String |
當要使用相對路徑導入同一個服務器下的其餘WEB應用程序中的資源時,context屬性指定其餘WEB應用程序的名稱 |
var |
false |
String |
指定將導入的資源內容保存到Web域中的屬性名稱 |
scope |
false |
String |
指定將導入的資源內容保存到哪一個Web域中 |
charEncoding |
true |
String |
將導入的資源內容轉換成字符串時所使用的字符集編碼 |
varReader |
false |
String |
指定將導入的資源內容保存到page域中的一個java.io.Reader對象中,varReader屬性指定了該Reader對象在page這個Web域中的屬性名稱。 |
使用<c:import>標籤導入其餘資源文件時,若是被導入的資源文件中含有非ASCII碼字符,必須注意指定charEncoding屬性,不然能夠不設置這個屬性。
當使用第1種語法格式時,若是指定了var屬性,導入的資源內容以字符串形式保存到一個變量中,var屬性指定了這個變量保存在Scope屬性指定的Web域中的名稱;若是沒有指定var屬性,導入的資源內容將以字符串形式直接輸出。第1種語法格式的標籤體內中能夠嵌套<c:param>標籤來給導入的資源傳遞參數。
使用第2種語法格式時,導入的資源內容保存到page域中的一個java.io.Reader對象中,varReader屬性指定了該Reader對象在page這個Web域中的屬性名稱。由於<c:import>標籤在標籤結束時將關閉Reader對象對應的輸入流,因此varReader屬性指定的變量只在標籤內有效。第2種語法格式的標籤體內中應該且只能嵌套調用varReader屬性指定的reader對象的其餘標籤。當使用第2種語法格式時,<c:import>標籤體內不能嵌套<c:param>標籤,若是要給導入的資源傳遞參數,則必須在url屬性值中設置好這些參數,這時可使用<c:url>標籤來建立一個帶參數的URL地址,此時若是有必要,<c:import>標籤將刪除導入資源中的全部URL重寫後產生的session id信息。
使用<c:import>標籤導入外部資源文件時,url屬性能夠設置爲被導入資源的相對URL或絕對URL。
1.使用相對URL導入其餘資源文件
(1)當被導入的外部資源文件與當前JSP文件屬於同一個WEB應用程序時,JSP容器對資源路徑的處理與<jsp:include>標籤相同,這時路徑能夠以「/」字符開始,也能夠以文件名或目錄名開始。若是路徑以「/」字符開始,則被導入資源文件的路徑是相對於JSP頁面所在的WEB應用的根路徑;若是路徑以文件名或目錄名開始,則被導入的資源文件的路徑就是相對於當前的JSP頁面的路徑。
(2)當被導入的外部資源文件與JSP文件屬於同一個服務器下的不一樣的WEB應用時,若是要使用相對路徑,路徑必須以「/」開始。此時,<c:import>標籤的context屬性必須被設置爲被導入的資源文件所在的WEB應用程序的名稱。注意:使用相對路徑導入其它WEB應用程序中的資源時,必須在<TOMCAT_HOME>\conf\server.xml配置文件中將使用<c:import>標籤的WEB應用程序的<Context>元素的crossContext屬性設置爲true,以下所示:
<Context path="/JSTL" docBase="JSTL" crossContext="true"/>
2.使用絕對URL導入其餘資源
使用絕對路徑導入外部資源文件時,即便被導入的文件與當前JSP文件屬於同一個WEB應用程序,被導入的資源文件也不會共享當前JSP頁面的request和session對象。由於在這種狀況下,當前JSP文件所屬的Web服務器充當了一個Http客戶端程序,去訪問絕對路徑所指定的外部資源文件,而後將響應結果的實體內容加入到當前JSP頁面中,此時,訪問當前JSP頁面的客戶端是瀏覽器,而訪問絕對路徑所指定的外部資源文件的客戶端是當前JSP文件所屬的Web服務器,這顯然屬於兩個不一樣的客戶端,因此,被導入的資源文件和當前JSP頁面不可能共享request和session對象。
例程8-23是使用<c:import>標籤的一個應用舉例。
例程8-23 c_import.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
使用相對路徑導入同一個WEB應用中的資源:<br />
<c:import url="/register.jsp?name=zhangsan">
<c:param name="name" value="zxx" />
</c:import><hr />
使用相對路徑導入同一個服務器下的不一樣WEB應用中的資源:<br />
<c:import url="/hello.jsp" context="/EL" /><hr />
使用絕對路徑導入資源示例1:
<c:import url="http://localhost:8080/EL/hello.jsp" /><hr />
使用絕對路徑導入資源示例2:
<c:import url="http://localhost:8080/JSTL/register.jsp" var="myImport"
charEncoding="gb2312">
<c:param name="name" value="${param.name}" />
<c:param name="country" value="中國" />
</c:import>
${myImport}
在瀏覽器地址欄輸入以下地址訪問例程8-23,其運行結果如圖8.20 所示:
http://localhost:8080/JSTL/c_import.jsp?name=zxx&country=China
圖8.20
在<c:import>標籤中使用相對路徑導入其餘資源時,其工做原理與<jsp:include>標籤相同,因此,在被導入的資源文件中能夠得到傳遞給當前JSP頁面的請求參數,例如,例程8-23中的第一個<c:import>標籤並無在目標url後增長country參數,可是,在register.jsp頁面中得到了country參數。
<c:redirect>標籤用於將當前的訪問請求轉發或重定向到其餘資源,它能夠根據url屬性所指定的地址,執行相似<jsp:forward>這個JSP標準標籤的功能,將訪問請求轉發到其餘資源;或執行response.sendRedirect()方法的功能,將訪問請求重定向到其餘資源。<c:redirect>標籤有兩種語法格式:
語法1,沒有標籤體的狀況:
<c:redirect url="value" [context="context"] />
語法2,有標籤體的狀況,在標籤體中指定重定向時的參數:
<c:redirect url="value" [context="context"]>
<c:param>subtags
</c:redirect>
<c:redirect>標籤的屬性說明如表8.11所示。
表8.11 <c:redirect>標籤的屬性
屬性名 |
是否支持EL |
屬性類型 |
屬 性 描 述 |
url |
true |
String |
指定要轉發或重定向到的目標資源的URL地址 |
context |
true |
String |
當要使用相對路徑重定向到同一個服務器下的其餘WEB應用程序中的資源時,context屬性指定其餘WEB應用程序的名稱 |
url屬性指定將要重定向的資源的URL時,可使用相對路徑和絕對路徑,其具體細節與<c:import>標籤的url屬性相同。例程8-24是一個使用<c:redirect>標籤的應用例子。
例程8-24 c_redirect.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=gb2312" %>
<c:url value="http://localhost:8080/JSTL/URL/register.jsp" var="myUrl">
<c:param name="name" value="張三" />
<c:param name="country" value="中國" />
</c:url>
<c:redirect url="${myUrl}" />
例程8-24的運行結果如圖8.21 所示。
圖8.21