JSTL核心标签库包含了一组用于实现WEB应用中的通用操作的标签,JSP规范为核心标签库建议的前缀名为c。
1.3.1 <c:out>标签
<c:out> 标签用于输出一段文本内容到pageContext对象当前保存的“out”对象中,在通常情况下,pageContext对象当前保存的“out”对象 的数据是输出到客户端浏览器,所以,<c:out> 标签通常用于输出一段文本内容到客户端浏览器。如果<c:out> 标签输出的文本内容中包含了需要进行转义的HTML特殊字符,例如,<、>、'、"、&等,<c:out> 标签默认对它们按表1.2进行HTML编码转换后再进行输出,这样就可以在浏览器中显示出这些字符。
表1.2 特殊字符转换
<c:out>标签标签有两种语法格式:
语法1,没有标签体的情况:
<c:out value="value"
[escapeXml="{true|false}"]
[default="defaultValue"] />
语法2,有标签体的情况,在标签体中指定输出的默认值:
<c:out value="value"
[escapeXml="{true|false}"] >
default value
</c:out>
<c:out>标签的属性说明如表1.3所示。
表1.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>标签将对要输出的特殊字符按表1.2 进行转换;如果将escapeXml属性设置为false,<c:out>标签将不对要输出的特殊字符进行转换,而是直接输出这些特殊字符。
例程1-3是<c:out> 标签的一个演示例子程序。
例程1-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}" />
例程1-3的运行结果如图1.1所示。
图1.1
例程1-4和例程1-5是两个用于演示<c:out>标签的escapeXml属性的例子程序,例程1-4没有设置escapeXml属性,例程1-5将escapeXml属性设置为了false。
例程1-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>
例程1-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>
例程1-4和例程1-5的运行结果分别如图1.2和图1.3所示。
图1.2
图1.3
1.3.2 <c:set>标签
<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>标签的属性说明如表1.4所示。
表1.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。
例程1-6是使用<c:set>标签设置某个Web域中的属性的一个演示例子程序。
例程1-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}" />
例程1-6的运行结果如图1.4所示。
图1.4
例程1-7是使用<c:set>标签设置UserBean对象和Map对象的属性的一个演示例子程序。
例程1-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}" />
在浏览器地址栏输入如下地址访问例程1-7:
http://localhost:1010/JSTL/c_set2.jsp?color=green
例程1-7的运行结果如图1.5所示。
图1.5
1.3.3 <c:remove>标签
<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时的作用相同。
例程1-1是使用<c:remove>标签的一个演示例子程序。
例程1-1 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}" />
例程1-1的运行结果如图1.6所示。
图1.6
1.3.4 <c:catch>标签
<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>标签进行捕获处理。
例程1-9是使用<c:catch>标签进行异常捕获处理的一个演示例子程序。
例程1-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}" />
在例程1-9中,<c:catch>标签内嵌套的脚本元素抛出了异常,<c:catch var="myex">将捕获到这个异常,调用<c:out value="${myex.message}" />,相当于调用<%=myex.getMessage()%>。例程1-9的运行结果如图1.7所示。
图1.7
1.3.5 <c:if>标签
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>标签的属性说明如表1.5所示。
表1.5 <c:if>标签的属性
属性名 |
是否支持EL |
属性类型 |
属 性 描 述 |
test |
true |
boolean |
决定是否处理标签体中的内容的条件表达式 |
var |
false |
String |
用于指定将test属性的执行结果保存到某个Web域中的某个属性的名称 |
scope |
false |
String |
指定将test属性的执行结果保存到哪个Web域中 |
对于语法2,如果指定了<c:if>标签的scope属性,则必须指定var属性。
例程1-10是使用<c:if>标签的一个演示例子程序。
例程1-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>
在浏览器地址栏输入如下地址访问例程1-10:
http://localhost:1010/JSTL/c_if.jsp?count=1
例程1-10的运行结果如图1.1所示。
图1.1
1.3.6 <c:choose>标签
<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>标签,则不执行任何操作。
例程1-11是使用<c:choose>、<c:when>、<c:otherwise>标签的一个演示例子程序。
例程1-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>
在浏览器地址栏输入如下地址访问例程1-11:
http://localhost:1010/JSTL/c_choose.jsp?count=0
例程1-11的运行结果如图1.9所示。如果将参数count的值修改为10,则运行结果如图1.10所示。
图1.9
图1.10
例程1-12是一个综合使用<c:if>标签和<c:choose>等标签的例子程序,在这个例子程序中,首先使 用<c:if>标签判断表单提交的方式是否是POST,如果是,就再使用<c:choose>等标签根据表单提交的内容进行不同 的处理。
例程1-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的运行结果如图1.11所示,在文本框中输入“computer”,单击其中的submit按钮后的运行结果如图1.12所示。
图1.11
图1.12
1.3.7 <c:forEach>标签
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>标签的属性说明如表1.6所示。
表1.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),这 些数据类型将在1.5 节的数据库标签中进行介绍。对字符串的迭代操作通常使用<c:forTokens>标签或JSTL函数,例如fn:split和 fn:jion,JSTL函数将在1.7节进行介绍。