9.3.7 <c:forEach>标签

优质
小牛编辑
125浏览
2023-12-01

<c:forEach>标签用于根据集合对象或指定的次数循环迭代标签体中的内容。<c:forEach>标签有如下两种语法格式:

1 语法1:根据集合对象进行迭代

<c:forEach[var="varName"] items="collection"
[varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>

2 语法2:根据指定的次数进行迭代

<c:forEach [var="varName"]
[varStatus="varStatusName"]
begin="begin" end="end" [step="step"]>
    body content
</c:forEach>

<c:forEach>标签的属性说明如表9.7所示。

表9.7 <c:forEach>标签的属性

属性名

是否支持动态属性值

属性类型

属性描述

var

false

String

指定将当前迭代元素保存在page域中的属性名。

items

true

任何支持的类型

用于迭代的集合对象。

varStatus

false

String

指定将表示当前迭代元素状态信息的对象保存在page域中的属性名。当前迭代元素的状态信息对象实际上是javax.servlet.jsp.jstl.core.LoopTagStatus类的对象实例。

begin

true

int

如果指定items属性,就从集合中第begin个元素开始迭代。begin属性的索引值从0开始编号。如果未指定items属性,那从begin属性指定的值开始迭代,直到end属性指定的值结束。

end

true

int

如果指定items属性,则迭代到第end个集合元素为止。如果未指定items属性,则迭代到end属性所指定的值为止。

step

true

int

指定迭代的步长,即每迭代一步的迭代增量。

在使用<c:forEach>标签时应注意如下几点:

1 如果指定begin属性,该属性的值必须大于或等于0,否则会抛出javax.servlet.jsp.JspTagException异常。

2 如果指定end属性,该属性的值不能小于begin属性的值,否则不会进行迭代操作。

3  如果指定step属性,该属性的值必须大于或等于1,否则会抛出javax.servlet.jsp.JspTagException异常。

4 如果items属性的值为null,或items属性指定的集合对象不存在,items属性值将被作为一个空集合对待。<c:forEach>标签不会进行迭代操作。

5 如果begin属性值大于或等于集合对象的元素个数,则不会进行迭代操作。

6 如果begin属性值在有效的范围内,但end属性值大于或等于集合对象的元素个数,则迭代到集合对象的最后一个元素为止。

<c:forEach>标签的items属性支持如下的数据类型:

7 任意类型的数组

8 java.util.Collection

9 java.util.Iterator

10  java.util. Enumeration

11  java.util.Map

12  String

如果items属性值是String类型,该字符串必须用逗号(,)分隔。<c:forEach>标签会将以逗号分隔的字符串当作String数组来处理(每一个被逗号分隔的子串相当于String数组中的一个元素)。

1. 迭代数组

forEach_array.jsp页面是一个使用<c:forEach>标签迭代数组的例子,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
    String[] strArray = new String[]{"超人", "飞机", "神化", "地球"};
    int[] intArray = new int[]{100, 200, 320, 400, 1200};
    chapter9.Message[] messages = new chapter9.Message[3];
    messages[0] = new chapter9.Message();
    messages[0].setName("bill");
    messages[1] = new chapter9.Message();
    messages[1].setName("Mike");
    messages[2] = new chapter9.Message();
    messages[2].setName("赵明");
    //  将数组保存在request域中
    request.setAttribute("strArray", strArray);
    request.setAttribute("intArray", intArray);
    request.setAttribute("messages", messages);
%>
迭代输出String数组中的元素<br>
<c:forEach var="str" items="${strArray}" >
${str}
</c:forEach>
<hr>
迭代输出int数组中的元素,并指定begin、end和varStatus属性<br>
<c:forEach var="int" items="${intArray}" begin = "1" end = "3" varStatus="status" >
intArray[${status.index}]=${int}&nbsp;&nbsp;&nbsp;
</c:forEach>
<hr>
迭代Message对象数组,并通过step属性指定迭代步长<br>
<c:forEach var="message" items="${messages}" step="2" varStatus="status">
messages[${status.index}].name =${message.name}<br>
</c:forEach>

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach_array.jsp

浏览器的显示结果如图9.9所示。

09

图9.9 使用<c:forEach>标签迭代数组

2. 迭代Collection和Iterator类型的集合对象

forEach_collection.jsp页面是一个使用<c:forEach>标签迭代Collection和Iterator类型的集合对象的例子,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
    java.util.List<Object[]> objList = new java.util.ArrayList<Object[]>();
    java.util.Random random = new java.util.Random();
    for (int i = 0; i < 7; i++)
    {
        Object[] objArray = new Object[]
        { "随机数" + String.valueOf(i + 1), random.nextInt(10000) };
        objList.add(objArray);
    }
    //  将Collection和Iterator类型的集合对象保存在request域中
    request.setAttribute("objList", objList);
    request.setAttribute("objIterator", objList.iterator());
%>

<table width="100%">
    <tr>
        <td align="right" style="padding-right: 20px">
        <table border="1">
            <tr>
                <th>名称</th>
                <th>随机数</th>
            </tr>
            <!--  迭代Collection类型的集合对象  -->
            <c:forEach var="obj" items="${objList}">
                <tr>
                    <td>${obj[0]}</td>
                    <td>${obj[1]}</td>
                </tr>
            </c:forEach>
        </table>
        </td>
        <td style="padding-left: 20px">
        <table border="1">
            <tr>
                <th>随机数</th>
                <th>名称</th>
            </tr>
          <!--  迭代Iterator类型的集合对象  -->
            <c:forEach var="obj" items="${objIterator}" >
                <tr>
                    <td>${obj[1]}</td>
                    <td>${obj[0]}</td>
                </tr>
            </c:forEach>
        </table>
        </td>
    </tr>
</table>

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach_collection.jsp

浏览器显示的结果如图9.10所示。

10

图9.10 使用<c:forEach>标签迭代Collection和Iterator类型的集合对象

3. 使用双重循环迭代Enumeration类型的集合对象和数组

forEach_enumeration.jsp页面是一个使用<c:forEach>标签迭代Enumeration类型的集合对象和数组的例子。内层循环迭代数组,外层循环迭代Enumeration类型的集合,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
    java.util.Vector v = new java.util.Vector();
    String[] strArray = new String[]
    { "超人", "飞机", "神化", "地球" };
    int[] intArray = new int[6];
    java.util.Random random = new java.util.Random();
    for (int i = 0; i < intArray.length; i++)
    {
        intArray[i] = random.nextInt(123456);
    }
    v.add(strArray);
    v.add(intArray);
    //  将Enumeration对象保存在request域中
    request.setAttribute("elements", v.elements());
%>
使用双重循环输出Enumeration对象中的值<hr>
<!--  迭代Enumeration集合对象  -->
<c:forEach var="element" items="${elements}">
    <!--  迭代Enumeration集合对象中的元素,每一个元素是一个数组  -->
    <c:forEach var="value" items="${element}">
        ${value}
    </c:forEach>
    <br>
</c:forEach>

Vector对象的elements方法返回了一个Enumeration对象。该对象描述了Vector对象中的所有元素。

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach_enumeration.jsp

浏览器显示的结果如图9.11所示。

11

图9.11 使用双重循环迭代Collection类型的集合对象和数组

4. 迭代Map类型的集合对象

foreach_map.jsp页面是一个使用<c:forEach>标签迭代Map类型的集合对象的例子,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
    java.util.Map<String, Integer> map = new java.util.HashMap<String, Integer>();
    map.put("自行车", 23);
    map.put("皮球", 20);
    map.put("电脑", 120);
    //  将Map对象保存在request域中
    request.setAttribute("map", map);
%>

<br>
<center>迭代输出Map对象中的key-value对<p/>
    <table border="1">
        <tr>
            <th>商品</th>
            <th>数量</th>
        </tr>

        <!--   迭代Map类型的集合对象 -->

        <c:forEach var="entry" items="${map}">
            <tr>
                <!-- 输出集合元素的key -->
                <td>${entry.key}</td>
                <!-- 输出集合元素的value --
                <td>${entry.value}</td
            </tr>
        </c:forEach>
    </table>
</center>

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach_map.jsp

浏览器显示的结果如图9.12所示。

12

图9.12 使用<c:forEach>标签迭代Map类型的集合对象

5. 迭代用逗号(,)分隔的字符串

<c:forEach>标签除了可以迭代各种类型的集合对象和数组外,还可以迭代用逗号分隔的字符串。但要注意,分隔符必须是逗号。forEach_string.jsp页面是一个使用<c:forEach>标签迭代以逗号分隔的字符串的例子,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<center>
    <table border="1">
        <tr>
           <!--   迭代用逗号分隔的字符串 -->
            <c:forEach var="s" items="超人, 飞机, 神化, 地球">
                <td>${s}</td>
            </c:forEach>
        </tr>
    </table>
</center>

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach_string.jsp

浏览器显示的结果如图9.13所示。

13

图9.13 使用<c:forEach>标签迭代以逗号分隔的字符串

6. 获得当前迭代元素的状态信息

通过<c:forEach>标签的status属性可以指定保存当前迭代元素状态信息的对象名。该对象被保存在page属性。这个对象实际上就是javax.servlet.jsp.jstl.core.LoopTagStatus对象实例。在LoopTagStatus接口有如下几个方法可以获得当前迭代元素的状态信息:

1 public Object getCurrent():该方法返回当前迭代的元素对象。

2 public int getCount():该方法返回当前已循环迭代的次数。

3 public int getIndex():该方法返回当前迭代的元素索引号。

4 public boolean isFirst():如果当前迭代元素是迭代集合对象的第一个元素,该方法返回true,否则返回false。

5 public boolean isLast():如果当前迭代元素是迭代集合对象的最后一个元素,该方法返回true,否则返回false。

6 public Integer getBegin():该方法返回<c:forEach>标签的begin属性值。如果未设置begin属性,则返回null。

7 public Integer getEnd():该方法返回<c:forEach>标签的end属性值。如果未设置end属性,则返回null。

8 public Integer getStep():该方法返回<c:forEach>标签的step属性值。如果未设置step属性,则返回null。

forEach_status.jsp页面是一个使用<c:forEach>标签输出当前迭代元素状态信息的例子,代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
    String[] strArray = new String[]{ "超人", "飞机", "神化", "地球" };
    //  将数组保存在request域中
    request.setAttribute("strArray", strArray);
%>
<center>
未设置begin、end和step属性<p/>
<table border="1">
    <tr>
        <th>当前迭代元素</th>
        <th>current</th>
        <th>count</th>
        <th>index</th>
        <th>first</th>
        <th>last</th>
        <th>begin</th>
        <th>end</th>
        <th>step</th>
    </tr>
    <c:forEach var="s" items="${strArray}" varStatus="status">
        <tr>
            <td>${s}</td>
            <td>${status.current}</td>
            <td>${status.count}</td>
            <td>${status.index}</td>
            <td>${status.first}</td>
            <td>${status.last}</td> 
            <td>${status.begin}</td>
            <td>${status.end}</td> 
            <td>${status.step}</td>
        </tr>
    </c:forEach>
</table>
<hr>

设置了begin、end和step属性<p/>

<table border="1">
    <tr>
        <th>当前迭代元素</th>
        <th>current</th>
        <th>count</th>
        <th>index</th>
        <th>first</th>
        <th>last</th>
        <th>begin</th>
        <th>end</th>
        <th>step</th>
    </tr>
    <c:forEach var="s" items="${strArray}" varStatus="status" begin = "1" end = "3" step="2">
        <tr>
            <td>${s}</td>
            <td>${status.current}</td>
            <td>${status.count}</td>
            <td>${status.index}</td>
            <td>${status.first}</td>
            <td>${status.last}</td> 
            <td>${status.begin}</td>
            <td>${status.end}</td> 
            <td>${status.step}</td>
        </tr>
    </c:forEach>
</table>
</center>

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach_status.jsp

浏览器显示的结果如图9.14所示。

14

图9.14 使用<c:forEach>标签输出当前迭代元素的状态信息

7. 设置表格偶数行的背景色

使用迭代元素状态信息对象的属性可以实现很多有趣的功能。如使用count属性可以实现改变表格的偶数行背景色的功能,代码如下:

<!--  forEach.jsp  -->

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
    java.util.Map<String, Integer[]> map =
        new java.util.HashMap<String, Integer[]>();
    map.put("自行车", new Integer[]{ 321, 23 });
    map.put("皮球", new Integer[]{ 45, 20 });
    map.put("电脑", new Integer[]{ 4320, 120 });
    map.put("啤酒", new Integer[]{ 3, 320 });
    map.put("照相机", new Integer[]{ 1200, 12 });
    //  将Map对象保存在request域中
    request.setAttribute("map", map);
%>

<br>

<center>设置表格偶数行的背景色<p/>
    <table border="1" width="80%">
        <tr>
            <th>商品</th>
            <th>单价</th>
            <th>数量</th>
        </tr>
        <!--   迭代Map类型的集合对象 --> 
        <c:forEach var="entry" items="${map}" varStatus="status">
            <!-- 使用EL判断count属性值是否为偶数,以便设置偶数行的背景色 -->
            <tr ${status.count % 2 == 0? 'style="background-color:#00CCEE"':""}>
                <!-- 输出集合元素的key -->
                <td>${entry.key}</td> 
                <!-- 输出集合元素的value中的第一个元素 -->
                <td>${entry.value[0]}</td>
                <!-- 输出集合元素的value中的第二个元素 -->
                <td>${entry.value[1]}</td>
            </tr>
        </c:forEach>  
    </table>
</center>

在上面的代码中,使用了EL表达式判断了count属性值是否为偶数(不包括表头)。如果count属性值为偶数,则使用CSS设置了偶数行的背景色。

在浏览器地址栏中输入如下的URL:

http://localhost:8080/demo/chapter9/forEach.jsp

浏览器显示的结果如图9.15所示。

15

图9.15 设置表格偶数行的背景色