Board logo

标题: JSTL 入门 探讨 core(2)流控制 [打印本页]

作者: look_w    时间: 2018-7-15 08:43     标题: JSTL 入门 探讨 core(2)流控制

流控制由于可以用 EL 替代 JSP 表达式来指定动态属性值,因此页面创作人员无需使用脚本编制元素。因为脚本编制元素可能是引起 JSP 页面中维护问题的主要原因,所以 JSTL 的主要优点就在于提供了这样简单(且标准)的替代方法。
EL 从 JSP 容器检索数据,遍历对象层次结构,然后对结果执行简单的操作。不过,除了访问和操作数据之外,JSP 脚本编制元素的另一个常见用法是流控制。尤其是,页面创作人员常借助 scriptlet 来实现迭代或条件内容。然而,因为这样的操作超出了 EL 的能力,所以         core 库提供了几个定制操作来管理流控制,其形式有 、 和 。      
迭代在 Web 应用程序环境中,迭代主要用于访存和显示数据集,通常是以列表或表中的一系列行的形式显示。实现迭代内容的主要 JSTL 操作是         <c:forEach> 定制标记。该标记支持两种不同样式的迭代:整数范围上的迭代(类似 Java 语言的         for 语句)和集合上的迭代(类似 Java 语言的         Iterator 和         Enumeration 类)。      
进行整数范围迭代用到了清单 1 中所示的         <c:forEach> 标记的语法。         begin 和         end 属性要么是静态整数值,要么是可以得出整数值的表达式。它们分别指定迭代索引的初始值以及迭代索引的终止值。当使用         <c:forEach> 在整数范围内进行迭代时,这两个属性是必需的,而其它所有属性都是可选的。      
清单 1. 通过 <c:forEach> 操作进行数字迭代的语法
1
2
3
4
5
6
7
8
9
10
<c:forEach var="
        name" varStatus="
        name"
    begin="
        expression" end="
        expression" step="
        expression">
   
        body content
</c:forEach>




当出现         step 时,它也必须是整数值。它指定每次迭代后索引的增量。这样,迭代索引从         begin 属性的值开始,以         step 属性的值为增量进行递增,在迭代索引超过         end 属性的值时停止迭代。注:如果省略了         step 属性,那么步长缺省为 1。      
如果指定了         var 属性,那么将会创建一个带有指定名称的并限定了作用域的变量,并将每次迭代的当前索引值赋给该变量。这一限定了作用域的变量具有嵌套式可视性 ― 只可以在         <c:forEach> 标记体内对其进行访问。(我们很快将讨论可选属性         varStatus 的用法。)清单 2 显示了对一组固定整数值进行迭代的         <c:forEach> 操作示例。      
清单 2. 使用 <c:forEach> 标记来生成表列数据,这些数据对应于某一范围内的数值
1
2
3
4
5
6
7
8
<table>
<tr><th>Value</th>
    <th>Square</th></tr>
<c:forEach var="x" begin="0" end="10" step="2">
  <tr><td><cut value="${x}"/></td>
      <td><cut value="${x * x}"/></td></tr>
</c:forEach>
</table>




如图 3 中所示,上面的示例代码生成了一张表,显示前五个偶数及其平方。这是通过将         begin 和         step 属性值指定为 2,而将         end 属性值指定为 10 实现的。此外,用         var 属性创建用于存储索引值的限定了作用域的变量,         <c:forEach> 标记体内引用了该变量。尤其是,使用了一对         <cut> 操作来显示索引及其平方,其中索引的平方是使用一个简单的表达式计算得来的。      
图 3. 清单 2 的输出在对集合的成员进行迭代时,用到了         <c:forEach> 标记的另一个属性:         items 属性,清单 3 中显示了该属性。当使用这种形式的         <c:forEach> 标记时,         items 属性是唯一必需的属性。         items 属性的值应该是一个集合,对该集合的成员进行迭代,通常使用 EL 表达式指定值。如果变量名称是通过         <c:forEach> 标记的         item 属性指定的,那么对于每次迭代该已命名变量都将被绑定到集合后续元素上。      
清单 3. 通过 <c:forEach> 操作对集合进行迭代的语法
1
2
3
4
5
6
7
8
9
10
11
<c:forEach var="
        name" items="
        expression" varStatus="
        name"
    begin="
        expression" end="
        expression" step="
        expression">
   
        body content
</c:forEach>




<c:forEach> 标记支持 Java 平台所提供的所有标准集合类型。此外,您可以使用该操作来迭代数组(包括基本类型数组)中的元素。表 1 列出了         items 属性所支持的所有值。正如表的最后一行所指出的那样,JSTL 定义了它自己的接口         javax.servlet.jsp.jstl.sql.Result ,用来迭代 SQL 查询的结果。(我们将在本系列后面的文章中详细讨论这一功能。)      
表 1. <c:forEach> 标记的         items 属性所支持的集合      items 的值              所产生的                 item 值              java.util.Collection调用               iterator() 所获得的元素            java.util.Mapjava.util.Map.Entry 的实例            java.util.Iterator迭代器元素java.util.Enumeration枚举元素Object 实例数组            数组元素基本类型值数组经过包装的数组元素用逗号定界的               String子字符串javax.servlet.jsp.jstl.sql.ResultSQL 查询所获得的行
可以使用         begin 、         end 和         step 属性来限定在迭代中包含集合中哪些元素。和通过         <c:forEach> 进行数字迭代的情形一样,在迭代集合中的元素时同样要维护一个迭代索引。         <c:forEach> 标记实际上只处理那些与索引值相对应的元素,这些索引值与指定的         begin 、         end 和         step 值相匹配。      
清单 4 显示了用来迭代集合的         <c:forEach> 标记。对于该 JSP 代码段,         entryList 这一限定了作用域的变量被设置成了         Entry 对象列表(确切的说,         ArrayList )。         <c:forEach> 标记依次处理列表中的每个元素,将其赋给一个限定了作用域的变量         blogEntry ,然后生成两个表行 ― 一个用于 Weblog 项的         title ,另一个则用于该项         text 。这些特性是通过一对带有相应 EL 表达式的         <cut> 操作从         blogEntry 变量检索得到的。注:由于 Weblog 项的标题和文本都可能包含 HTML 标记,因此这两个         <cut> 标记的         escapeXml 属性都被设置成了 false。图 4 显示了结果。      
清单 4. 使用 <c:forEach> 标记显示表示给定日期的 Weblog 项
1
2
3
4
5
6
7
8
9
10
<table>
  <c:forEach items="${entryList}" var="blogEntry">
    <tr><td align="left" class="blogTitle">
      <cut value="${blogEntry.title}" escapeXml="false"/>
    </td></tr>
    <tr><td align="left" class="blogText">
      <cut value="${blogEntry.text}" escapeXml="false"/>
    </td></tr>
  </c:forEach>
</table>




图 4. 清单 4 的输出不论是对整数还是对集合进行迭代,         <c:forEach> 剩余的属性         varStatus 所起的作用相同。和         var 属性一样,         varStatus 用于创建限定了作用域的变量。不过,由         varStatus 属性命名的变量并不存储当前索引值或当前元素,而是赋予         javax.servlet.jsp.jstl.core.LoopTagStatus 类的实例。该类定义了一组特性,它们描述了迭代的当前状态,表 2 中列出了这些特性。      
表 2. LoopTagStatus 对象的特性特性Getter描述currentgetCurrent()当前这次迭代的(集合中的)项indexgetIndex()当前这次迭代从 0 开始的迭代索引countgetCount()当前这次迭代从 1 开始的迭代计数firstisFirst()用来表明当前这轮迭代是否为第一次迭代的标志lastisLast()用来表明当前这轮迭代是否为最后一次迭代的标志begingetBegin()begin 属性值            endgetEnd()end 属性值            stepgetStep()step 属性值            
清单 5 显示了关于如何使用         varStatus 属性的一个示例。这个示例修改了清单 4 中的代码,将 Weblog 项的编号添加到显示 Weblog 标题(title)的表行。它是通过为         varStatus 属性指定一个值,然后访问所生成的限定了作用域的变量的         count 特性来实现这一点的。结果显示在图 5 中。      
清单 5. 使用 varStatus 属性来显示 Weblog 项的数目
1
2
3
4
5
6
7
8
9
10
11
12
<table>
  <c:forEach items=
    "${entryList}" var="blogEntry" varStatus="status">
    <tr><td align="left" class="blogTitle">
      <cut value="${status.count}"/>.
      <cut value="${blogEntry.title}" escapeXml="false"/>
    </td></tr>
    <tr><td align="left" class="blogText">
      <cut value="${blogEntry.text}" escapeXml="false"/>
    </td></tr>
  </c:forEach>
</table>




图 5. 清单 5 的输出除         <c:forEach> 以外,         core 库还提供了另一个迭代标记:         <c:forTokens> 。JSTL 的这个定制操作与 Java 语言的         StringTokenizer 类的作用相似。清单 6 中显示的         <c:forTokens> 标记除了比         <c:forEach> 的面向集合版本多一个属性之外,其它属性都相同。对于         <c:forTokens> 而言,通过         items 属性指定要标记化的字符串,而通过         delims 属性提供用于生成标记的一组定界符。和         <c:forEach> 的情形一样,可以使用         begin 、         end 和         step 属性将要处理的标记限定为那些与相应索引值相匹配的标记。      
清单 6. 使用 <c:forTokens> 操作来迭代字符串标记的语法
1
2
3
4
5
6
7
8
9
10
11
12
13
<c:forTokens var="
        name" items="
        expression"
    delims="
        expression" varStatus="
        name"
    begin="
        expression" end="
        expression" step="
        expression">
   
        body content
</c:forTokens>






欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0