15.4 条件标签
条件标签能够实现Java语言中的if语句及if-else语句的功能,它包括以下几种。
<c:if> :用于实现Java语言中的if语句的功能。
<c:choose> 、<c:when>和<c:otherwise>:用于实现Java语言中的if-else语句的功能。
15.4.1 <c:if> 标签
<c:if> 标签用于实现Java语言中的if语句的功能,它的语法为:
1. <c:if test = " 逻辑表达式 "
2. var = " 代表逻辑表达式的值的命名变量的名字 "
3. scope = "{page|request|session|application}" / >
<c:if> 标签会把逻辑表达式的值存放在var属性指定的命名变量中,scope属性则指定命名变量的范围,scope属性的默认值是page(页面范围)。
例如以下<c:if>标签先判断username请求参数的值是否为Tom,然后把判断结果作为result命名变量存放在请求范围内:
1. <c:if test = "${param.username=='Tom'}" var = "result" scope = "request" />
2. ${result}
以上<c:if>标签等价于以下Java程序片段:
1. < %
2. String username = request .getParameter("username");
3. if(username!=null && username.equals("Tom"))
4.  request.setAttribute("result",true);
5. else
6.  request.setAttribute("result",false);
7. % >
<c:if> 标签还可以包含标签主体,只有当逻辑表达式的值为true时,才会执行标签主体。例如:
1. <c:if test = "${param.save=='user'}" >
2.  Saving user
3. <c:set var = "user" value = "Tom" />
4. </c:if>
以上<c:if>标签等价于以下Java程序片段:
1. < %
2. String save = request .getParameter("save");
3. if(save!=null && save.equals("user")){
4.  // 对应 <c:if> 标签的主体
5.  out.print("Saving user")
6.  pageContext.setAttribute("user","Tom");
7. }
8. % >

15.5 迭代标签

迭代标签包括以下几种。

<c:forEach>:用于遍历集合中的对象,并且能重复执行标签主体。

<c:forTokens>:用于遍历字符串中用特定分隔符分隔的子字符串,并且能重复执行标签主体。


15.5.1 <c:forEach> 标签(1)
<c:forEach> 标签用于遍历集合中的对象,并且能重复执行标签主体,它和本书第13章的13.4节(创建和使用iterate标签)介绍的<iterate>标签的作用有些相似。
1 .基本语法
<c:forEach> 标签的基本语法为:
1.<c:forEachvar="代表集合中的一个元素的命名变量的名字"items="集合">
2.标签主体
3.</c:forEach>
<c:forEach> 标签每次从集合中取出一个元素,并且把它存放在NESTED范围内的命名变量中,在标签主体中可以访问这个命名变量。NESTED范围是指当前标签主体构成的范围,只有当前标签主体才能够访问NESTED范围内的命名变量。
例如以下代码先创建了一个names集合,然后通过<c:forEach>标签遍历这个集合,并打印集合中的所有元素:
1.<%@ page import="java.util.HashSet" %>
2.<% 
3.HashSet names=new HashSet(); 
4.names.add("Tom"); 
5.names.add("Mike"); 
6.names.add("Linda"); 
7.%>
8.<c:forEachvar="name"items="<%=names %>">
9.  ${name} &nbsp; 
10.</c:forEach>
运行以上代码,得到的打印结果为"Tom Mike Linda"。以上<c:forEach>标签等价于以下Java程序片段:
1.<%@ page import="java.util.Iterator" %>
2.<% //第一个Java程序片段
3.  Iterator it=names.iterator(); 
4.  while(it.hasNext()){ 
5.    String name=(String)it.next(); 
6.    //把元素作为name命名变量存放在页面范围内
7.    pageContext.setAttribute("name",name); 
8.%>
9.
10.<% //第二个Java程序片段,对应<c:forEach>标签的主体
11.name=(String)pageContext.getAttribute("name"); 
12.    out.print(name+" "); 
13.%>
14.
15.<% //第三个Java程序片段
16.    pageContext.removeAttribute("name"); 
17.  } 
18.%>
以上第一个和第三个Java程序片段完成<c:forEach>标签的任务,即在每一次循环中,先从names集合中取出一个元素,把它作为name命名变量存放在页面范围内,接着执行标签主体,然后从页面范围内删除name命名变量,从而确保只有当前标签主体才能访问name命名变量。因此尽管在实现上,name命名变量位于页面范围,但是在逻辑上,name命名变量属于NESTED范围。
以上第二个Java程序片段完成<c:forEach>标签主体的任务,即从页面范围内读取name命名变量,并输出它的值。
2 .<c:forEach>标签的varStatus属性
<c:forEach> 标签的varStatus属性用于设定一个javax.servlet.jsp.jstl.core. LoopTagStatus类型的命名变量,它位于NESTED范围,这个命名变量包含了从集合中取出的当前元素的状态信息。
count :当前元素在集合中的序号,从1开始计数。
index :当前元素在集合中的索引,从0开始计数。
first :当前元素是否是集合中的第一个元素。
last :当前元素是否是集合中的最后一个元素。
例程15-2的namelist.jsp中的<c:forEach>标签就使用了varStatus属性。
例程15-2 namelist.jsp
1.<%@ page contentType="text/html; charset=GB2312" %>
2.<%@ taglib prefix="c"uri="http://java.sun.com/jsp/jstl/core" %>
3.<%@ page import="java.util.HashSet" %>
4.
5.<% 
6.HashSet names=new HashSet(); 
7.names.add("Tom"); 
8.names.add("Mike"); 
9.names.add("Linda"); 
10.%>
11.
12.<tableborder="1">
13.<tr>
14.<td>序号</td>
15.<td>索引</td>
16.<td>是否是第一个元素</td>
17.<td>是否是最后一个元素</td>
18.<td>元素的值</td>
19.</tr>
20.
21.<c:forEachvar="name"items="<%=names %>"varStatus="status">
22.<tr>
23.<td>${status.count} </td>
24.<td>${status.index} </td>
25.<td>${status.first} </td>
26.<td>${status.last} </td>
27.<td>
28.<c:choose>
29.<c:whentest="${status.last}">
30.<fontcolor="red">${name} </font>
31.</c:when>
32.<c:otherwise>
33.<fontcolor="green">${name} </font>
34.</c:otherwise>
35.</c:choose>
36.</td>
37.</tr>
38.</c:forEach>
39.</table>