JSTL tag library <%@ taglib %> directive
Core <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
XML <%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
Formatting <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
Database <%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>
<c:out>标记
<c:out>标记可以输出一个表达式的结果.
<c:out>标记的属性
属性 说明 是否必需 默认值
value 要计算的表达式 必需 无
default 如果计算表达式失败,使用的表达式 否 无
escapeXml 是否使用转义字符.如将'&'输出为"&" 否 true
3.1.1 What expressions look like
格式:${expression}
在${和}之间的内容被认为是表达式.表达式被认为是占位符,它们使用表达式语言进行计算,然后计算结果被输出.
<c:out value="${ 1+2 }"/>
表达式被计算,然后输出3
一旦一个表达式出现在JSTL标签的属性中,这时表达式被计算,其结果用于填充标记.
3.1.2 Where expressions work
在JSTL 1.0中,表达式只有在JSTL标签的属性中才有意义.特殊的,它们不能在模版文本中工作.
<p>Hi ${username}</p>将直接输出为文本.
3.1.3 Default values in <c:out>
如果value属性中的表达式失败,这时这个标记将不会输出任何东西.然而有时候,希望输出其他内容(如错误消息等),可以使用<c:out>的default属性来设置.
<c:out value="${username}" default="Nobody"/>
或者
<c:out value="${username}">
Nobody
</c:out>
3.1.4 Special characters and <c:out>
默认情况下,<c:out>确保任何对HTML或XML有特殊意义的字符是能够使用实体引用被正确转义.对XML有特殊意义的字符有(&,<,>,',"),默认情况下,如果使用<c:out>输出,包含的特殊字符被转义为&<等.转义使HTML浏览器显示该字符而不是把它们当作HTML或XML标记的一部分.
通过设置<c:out>标记的escapeXml属性为false,可以关闭<c:out>的转义功能.
3.2 Scoped varialbles and the expression language
JSTL的表达式语言主要目的是为了方便的访问数据.这些数据可以分成几类.
作用域变量典型的以两种方式中的一种创建:或者自己创建它们或者如果页面有后端Java代码支持,这些后端代码可以设置它们.
3.2.1 Basic syntax to access scope variables
在某种意义上说,JSTL表达式语言集中在作用域变量上.
一个象${username}的表达式意味着"名称为username的作用域变量".
当一个作用域变量名单独出现在一个表达式中时,它会引发表达式语言搜索所有JSP作用域去寻找这个变量.
page---->request---->session---->application
有时,可能需要返回特定作用域的变量,可以在表达式中命名特定的作用域.为了达到这个,在写表达式时以作用域名称开头,接着是Scope,然后是".".
示例表达式 意义
${pageScope.username} 页面作用域中的username变量
${requestScope.username} 请求域的username变量
${sessionScope.username} 回话作用域的username变量
${applicationScope.username} 应用作用域的username变量
3.2.2 Different types of scoped data
表达式语言支持很多数据类型.
Strings and numbers
一个string是一系列的字符组成的任意文本.人们通常使用string存储简单的文本信息.
当一个象<c:out>之类的标签指向一个字符串时,它输出这个字符串.
当<c:out>指向的不是一个字符串时,它将简单的将数据转换成字符串,然后输出.
作用域变量也可以存储数字.数字既可以是整型数也可以是浮点数.当有几个数时,可以使用JSTL表达式语言对它们进行简单的算术运算.
运算符 描述 简单表达式示例 结果
+ 加 ${10+2} 12
- 减 ${10-2} 8
* 乘 ${10*2} 20
/ 除 ${10/2} 5
% 取余 ${10%2} 0
除了这些运算符号,也可以使用-来使一个数变为相反数.
Booleans
一个布尔值有两个可能的值:true和false.这两个值也可以被解释成yes或no.
<c:out value="${username}" escapeXml="${status}"/>
这里假定status是一个布尔变量.
如果输出一个布尔变量,它的值简单的为true或false.
Collections
当一个作用域变量是一个字符串,数字或布尔值时,它的确只存放了一个:一段文字,一个数字或一个布尔值.有时,作用域变量可以存储整个对象的集合.
${sessionScope.shoppingCart}
一般有两种集合:
1>存放排好序的项目列表,余编程语言的数组类似.
${sessionScope.shoppingCart[0]}...等进行引用.
2>第二种方式的集合存储项目组,以名字来组织.
${sessionScope.user.username}
3.3 Request parameters and the expression language
Jsp页面使用作用域变量来管理自己的数据.然而页面也可以接受来自外界的输入.这些信息通过请求参数以对页面可见.
3.3.1 HTML forms
HTML表达是允许用户在web应用程序中输入数据的常用方法.
表达式语言使得访问请求参数变得十分简单.
${param.username}用于访问请求中名字为username的参数的值.
所有的请求参数都是字符串值.
3.4 More powerful expressions
3.4.1 Different ways to access properties
可以使用"."操作符访问一个没有排列的集合的元素.也可以使用[]访问排好序的集合的元素.
然而当元素没有排序时,可以把元素名放在[]中的方式来访问.
${sessionScope.user["name"]}==${sessionScope.user.name}
3.4.2 Accessing other data with the expression language
到目前为止,可以有六种方式开始一个表达式:pageScope,requestScope,sessionScope,applicationScope,param和paramValues.另外,可以简单的使用任何作用域变量的名字来直接访问,就象${username}.
表达式${pageScope}指向页面作用域中所有变量的集合
表达式${param}执行页面请求的所有参数集合.
默认对象 描述
cookie 由浏览器发送过来的cookie值
header 由浏览器发送过来的头
headreValues 由浏览器发送过来的一个头的所有值
initParam 一个上下文初始化参数
pageContext 关于本页面的详细信息
Cookies
cookie是web服务器向用户发送的浏览器保留的持久性信息.
JSTL不提供任何设置cookie的方法.然而如果一个名为colorPreference的cookie可用,可以使用表达式${cookie.colorPreference}.
Headers
头是web服务期和web浏览器之间使用的用于后台相互交互的数据.当一个页面被加载时,有机会发送描述这次请求的头信息.头包含了浏览器类型,客户机地区信息和其他细节.
${header["User-Agent"]}
在极少情况下,可能要使用headerValues,如果一个浏览器发送了两个同名的头.
Initialization parameters
后端Java程序可以设置被称为上下文初始化参数的信息.
${initParam.headerUrl}
pageContext
可以通过${pageContext}访问的变量可以访问关于页面的一些细节.大部分时间,不需要使用此信息,也不必使用pageContext开头的表达式.
Expression Description Sample value
${pageContext.request.authType} 页面使用的授权类型 BASIC
${pageContext.request.remoteUser} 如果服务期管理授权,返回用户的ID djdavies
${pageContext.request.contextPath} web应用的名字 /examples
${pageContext.request.cookies} 页面cookie的一个有序集合(array) n/a
${pageContext.request.method} 进入页面使用的HTTP方法 GET
${pageContext.request.queryString} 页面的整个查询字符串 p1=value1&p2=value2
${pageContext.request.requestURL} 访问页面的URL http://server/app/page.jsp
${pageContext.session.new} 如果回话是新的true;否则false true
${pageContext.servletContext.serverInfo} JSP容器的信息 Apache Tomcat/5.0.0
${pageContext.exception.message} 描述页面发生的错误 "Something very,very bad happened"
3.4.3 Comparisons
可以使用表达式语言产生布尔值.
egg.
${2==2}返回true.
Operator Description Sample expression Result
== 相等 ${5==5} true
eq
!= 不等 ${5!=5} false
ne
< 小于 ${5<7} true
lt
> 大于 ${5>7} false
gt
<= 小于或等于 ${5 le 5} true
le
>= 大于或等于 ${5 ge 6} false
ge
可以使用这些运算符比较任何两个可以使用表达式语言访问的数字.
${user.weight gt user.IQ}
当想检查一个请求参数是否与一个特定的值相同时,比较特别有用.
${param.month == "May"}
check to see if a variable exists
可以使用empty关键字来测试一个变量是否存在
${empty param.choice}
如果choice存在,则返回true
3.4.4 Boolean operations and parentheses
可以使用and,or或not来连接多个布尔值,也可以使用&&,||和!.
${2==2 and 3==3}
3.4.5 Multiple expressions
egg.
<c:out value="Hi ${user.first} ${user.last}"/>
3.5 Saving data with <c:set>
很多JSTL标签允许创建作用域变量,最基本的是<c:set>
<c:set>基础很简单:它取一个表达式或表达式体,计算它,然后保存结果.
Attribute Description Required Default
value 要计算的表达式的值 No Use body
var 要存储的作用域变量的名字 Yes None
scope 要存储的作用域变量的作用域 No page
var属性告诉<c:set>要设置的作用域变量的名字.var属性经常被用于决定要设置的变量的名字.
scope属性告诉标签设置变量时使用的作用域,它采用4个属性:page,request,session和application.它是可选的,默认为request.
Using the value attribute
使用<c:set>可以有两种方法:使用或不使用value属性.
<c:set var="four" value="${3 + 1}"/>
Using the tag's body
<c:set var="eight">
<c:out value="${4*2}"/>
</c:set>
中间部分不能被输出到浏览器,而是被赋值给变量,即内部标签输出作为外部的输入.
When is <c:set> userful?
<c:set>在当你想要计算一次而使用很多次是很有用.
3.6 Deleting data with <c:remove>
<c:remove>标签与<c:set>相反,用于移出变量.
Attribute Description Required Default
var 要移出的作用域变量的名字 Yes None
scope 要移出的作用域变量的作用域 No Any
如果没有指定作用域,那么所有出现的变量都被移出.
3.7 Summary
表达式可以出现在除了var和scope之外的任何JSTL标签属性上
表达式以${开头以}结尾.当一个表达式可以出现时,多个表达式也可以同时出现.
默认情况下,表达式引用的作用域变量从page作用域,然后是request,session和application作用域.
可以使用表达式使其指向一个请求变量:${param.name}或${paramValues.name}
可以对数字执行基本的算术运算(+,-,*,/,%),执行比较(== eq != ne < lt > gt <= le >= gt),组合布尔变量(and or not),也可以判断变量是否丢失(empty).
<c:out>标签输出一个作用域变量.
<c:set>设置一个作用域变量的值.
<c:remove>删除一个作用域变量.
Chapter 4.Controlling flow with conditions
JSP页面载入的时候,它自己可以决定向客户端浏览器发送什么信息.关键是,页面的文字和观感可以每次改变.
JSTL流程控制有两种形式:
1>条件逻辑(条件)
使应用程序决定采取什么动作或跳过那个动作.
2>循环(迭代)
重复页面的一部分.
4.1 Different kinds of decisions
很多问题只有简单的yes或no,只有两种可能的状态:true或false.
4.2 Yes-or-no conditions with <c:if>
Attribute Description Required Default
test 要计算的条件式.如果为真,处理表达式体 Yes None
var 可以计算出布尔值的属性 No None
scope 可以计算布尔值的属性的作用域 No page
test属性定义了一个要计算的条件(布尔)表达式.
${param.firstName == 'Mildred'}
<c:if>标签的test属性接受任何布尔表达式.
<c:if test="${user.education == 'doctorate'}">
Dr.
</c:if>
<c:out value="${user.name}"/>
如果test属性计算值为 这时
false JSP页面忽略<c:if>标签,包括它的内容
true <c:if>标签输出它的内容
4.2.2 Using <c:if> within HTML tags
可以在页面的任何地方使用<c:if>标签.
<font size="2"
<c:if test="${user.education=='doctorate'}">
color="red"
</c:if>
>
<c:out value="${user.name}"/>
</font>
4.2.3 Multiple <c:if> tags
当<c:if>标签出现在页面的另一处时,它们互不影响.
<ul>
<c:if test="${error1}">
<li>Error 1 has occurred.</li>
</c:if>
<c:if test="${error2}">
<li>Error 2 has occurred.</li>
</c:if>
</ul>
4.2.4 Nested <c:if> tags
<c:if>标签也可以嵌套,这意味着它们可以出现在其他的<c:if>中
<c:if test="${error1 or error2}">
<ul>
<c:if test="${error1}">
<li>Error 1 has occurred.</li>
</c:if>
<c:if test="${error2}">
<li>Error 2 has occurred.</li>
</c:if>
</ul>
</c:if>
4.2.5 The var and scope attributes
它们创建了其他标签可以访问的作用域变量.
然而这里创建的作用域变量的值是布尔型---或者是true或者是false.它们的值对应与test表达式.var属性允许保存test的值,以便在页面以后使用.也可以使用scope属性将其设置为request,session或application作用域.
4.3 Mutually exclusive conditions with <c:choose>,<c:when>,and <c:otherwise>
4.3.1 Why JSTL has complex conditional tags
4.3.2 How the complex conditional tags work
<c:choose>标签很简单:它不需要任何参数,只是作为<c:when>和<c:otherwise>标签的容器.如果<c:when>和<c:otherwise>在<c:choose>之外,它们没有什么具体意义.
<c:when>标签与<c:if>相似:它有一个单独的test属性,只有在满足条件时才执行体.与<c:if>不同的是,对每个<c:choose>,最多只有一个<c:when>可以成功执行.如果一个<c:when>标签被执行,其他的<c:when>都被忽略.
<c:when>标签的属性
test 要计算的条件 必需 无默认
如果<c:when>标签都不被执行,这时可以使用<c:otherwise>标签.它不使用任何属性.
<c:choose>
<c:when test="${error1}">
<li>Error 1 has occurred.</li>
</c:when>
<c:when test="${error2}">
<li>Error 2 has occurred.</li>
</c:when>
<c:when test="${error3}"/>
<li>Error 3 has occurred.</li>
</c:when>
<c:otherwise>
<li>Everything is fine.</li>
</c:otherwise>
</c:choose>
另一个例子
<c:choose>
<c:when test="${user.education==’doctorate’}">
Dr.
</c:when>
<c:when test="${user.gender==’female’}">
Ms.
</c:when>
<c:when test="${user.gender==’male’}">
Mr.
</c:when>
</c:choose>
<c:out value="${user.name}"/>
4.3.3 Rules for using the complex conditional tags
每个<c:choose>标签必须至少含有一个<c:when>且最多只有一个<c:otherwise>.如果<c:otherwise>出现,则内部必须有一个<c:when>标签,且<c:otherwise>必须出现在最后.在<c:choose>中不能直接出现HTML标记或JSP标记.
Chapter 5. Controlling flow with loops
循环重复执行页面中同一段JSTL代码.循环经常被称为迭代.
<c:forEach>和<c:forTokens>标签用于处理循环.
5.1 General-purpose looping with <c:forEach>
<c:forEach>标签是JSTL的通用循环标签.<c:forEach>标签允许循环表达式语言返回的集合.
<c:forEach>标签的基本功能是通过items属性来定义集合中的每个项目.对于集合中的每一个项目,<c:forEach>标签将被处理一次,将当前项目使用<c:forEach>的var属性将其转换成页面作用域的变量.
<c:forEach items="${user.medicalConditions}" var="ailment">
<c:out value="${ailment}"/>
</c:forEach>
Attribute Description Required Default
items 要循环的集合 No None
var 当前项目赋予的变量 No None
5.2 Iterating over strings with <c:forTokens>
有时,数据不被组织成通常的集合.
分析一个字符串通常被称为解析.
Attribute Description Required Default
items 要循环的输入字符串 Yes None
delims 字符串的分隔符 Yes None
var 当前项目赋予的变量 No None
简而言之,<c:forTokens>标签使用items和delims属性来产生标记,然后将变量赋值给由var定义的变量中.
items属性引用到一个字符串.
items="a,b,c"
items="${emailAddresses}"
delims属性是包含要分割字符串中标记的字符.这些被称为分隔符.
delims=".,;:"
<c:forTokens items="a;b;c;d" delims=";" var="current">
<li><c:out value="${current}"/></li>
</c:forTokens>
5.2.1 How JSTL parses strings
由items定义的字符串,分隔符被认为是一个单独的.
5.3 Advanced iteration with <c:forEach> and <c:forTokens>
5.3.1 Looping over part of a collection
<c:forEach>和<c:forTokens>的其他属性
Attribute Description Required Default
begin 要开始循环的项目,0=第一个 No 0
end 最后的项目,0=第一个 No Last item
step 增量 No 1
JSTL给集合中的每个项目都列了一个索引,整个索引反映了项目在集合中的位置,这个索引从0开始.
begin和end属性接受这些索引值.默认情况下,<c:forEach>和<c:forTokens>处理整个集合中的所有可用的项目.
Java中使用基于0的索引.
<c:forTokens items="a,b,c,d,e,f" delims="," var="letter" begin="4">
<c:out value="${letter}"/>
</c:forTokens>
只有集合中实际存在的索引值可以被循环处理.如果begin处理了一个大于集合可用的值时,它们就不会作任何处理.如果end属性大于最高的索引,这时end属性无用.
5.3.2 Looping over numbers
要遍历数字,只能通过<c:forEach>
<c:forEach begin="1" end="5" var="current">
<c:out value="${current}"/>
</c:forEach>
将输出:1 2 3 4 5
<c;forEach begin="2" end="10" step="2" var="current">
<c:out value="${current}"/>
</c:forEach>
5.3.3 Loop status
<c:forEach>和<c:forTokens>标签同样有反映循环状态的变量.
Property Type Description
index number 当前项在集合中的位置
count number 集合中的当前遍历的个数
first boolean 当前项是否是第一项
last boolean 当前项是否是最后项
集合中的每一项都有一个索引,这些索引以0开始,每一项加一.
5.4 Loop example:crolling through results
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:set var="totalCount" scope="session" value="100"/>
<c:set var="perPage" scope="session" value="20"/>
<c:forEach
var="boundaryStart"
begin="0"
end="${totalCount - 1}"
step="${perPage}">
<a href="?start=<c:out value="${boundaryStart}"/>">
[
<c:out value="${boundaryStart}"/>
-
<c:out value="${boundaryStart + perPage - 1}"/>
]
</a>
</c:forEach>
<c:forEach
var="current"
varStatus="status"
begin="${param.start}"
end="${param.start + perPage - 1}">
<c:if test="${status.first}">
<ul>
</c:if>
<li><c:out value="${current}"/></li>
<c:if test="${status.last}">
</ul>
</c:if>
</c:forEach>
Chapter 6 Importing text
JSP中使用<%@page include%>和<jsp:include>来包含文件.JSTL引入了第三种机制<c:import>
<c:import>允许包含其他web服务器的内容.
6.1 Including text with the <c:import> tag
要从本地JSP页面或其他服务器取得内容,可以使用<c:import>标签.有时候,可能会输出取回的内容,而<c:import>允许将取回的文本放在作用域变量中.
Attribute Description Required Default
url 要请求的导入到当前页的URL Yes None
context /跟着本地WEB应用的名字 No 当前上下文
var 存取当前URL内容的变量名称 No None
scope 变量的作用域 No page
通常,被<c:import>调用的页面称为目标页面,调用者页面称为源页面.