JSTL Looping and Iteration Actions

One of the most common tasks you have to deal with in JSP is outputting a set of data by using the Java for and while loop. By doing so, you create a very unreadable JSP page with opening and closing curly brace. In addition, if an error occurred, it is difficult to detect the code that causes the problem.

Fortunately, JSTL provides you with two useful actions for looping and iteration: for general data and for a string of tokens.

The <c:forEach> action

The <c:forEach> action is very useful. You can loop over a collection or you can iterate a number of times. There are two usages of <c:forEach> action. Let’s take a look at the first one which you can use <c:forEach> for loop over a collection.

<c:forEach(var = "var" 
        items="collection" 
        varStatus="varStatusName">
<%-- processing of each item here --%>
</c:forEach>Code language: HTML, XML (xml)

The first two attributes are mandatory. You specify a collection in items attribute and each of item in the collection in the var attribute. The varStatus attribute is optional. the varStatus attribute is an instance of a class which implements interface LoopTagStatus. The varStatus attribute provides a set of useful properties to work with such as begin, end, current, index, and count.

Let’s take a look at an example:

<%@page contentType="text/html"
        pageEncoding="UTF-8"
        import="com.jsptutorial.*,java.util.*"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core"
          prefix="c" %>

<html>
    <head>
        <title>Looping with c:forEach</title>
    </head>
    <body>
        <%
            ArrayList<Person> list = new ArrayList<Person>();
            Person p1 = new Person("Abel", "William");
            Person p2 = new Person("Sarah", "Palin");
            Person p3 = new Person("David", "Nguyen");
            list.add(p1);
            list.add(p2);
            list.add(p3);
            request.setAttribute("list", list);
        %>

        <table border="1">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                </tr>
            </thead>
            <tbody>
                <c:forEach var="person" items="${requestScope.list}">
                <tr>
                    <td><c:out value="${person.firstName}"  /></td>
                    <td><c:out value="${person.lastName}" /></td>
                </tr>
                 </c:forEach>
            </tbody>
        </table>
    </body>
</html>Code language: PHP (php)

In the code example above we create a list that contains three people and put that list object into the request object of the page. Then we loop through the list of people and print out their first name and last name by using <c:forEach> action.

If you want the table to have an alternative row background color, you can use the varStatus to do so. Let’s take a look at the modified version of the example above.

First, we declare background color for odd and even rows by using the CSS class.

<style type="text/css">
  .odd{ background-color:#fff}
  .even{background-color:#ccc}
</style>

Then we use the varStatus attribute to access the LoopTagStatus object. Based on the current row of the iteration, we determine the odd and even row. Be noted that the current row of the iteration can be accessible via the count property of the LoopTagStatus object.

<table border="1">
    <thead>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
        </tr>
    </thead>
    <tbody>
    <c:forEach var="person"
               items="${requestScope.list}"
               varStatus ="row">

        <c:choose>
            <c:when test="${row.count % 2 == 0}">
                <c:set var="rowStyle" value="odd"  />
            </c:when>
            <c:otherwise>
                <c:set var="rowStyle" value="even"  />
            </c:otherwise>
        </c:choose>

        <tr>
            <td><c:out value="${person.firstName}"  /></td>
            <td><c:out value="${person.lastName}" /></td>
        </tr>
    </c:forEach>
</tbody>
</table>Code language: HTML, XML (xml)

The other usage of the <c:forEach> action is interaction in a number of times. Here is the syntax:

<c:forEach var="varName"
           varStatus="varStatusName"
           begin="begin" 
           end="end" 
           step="step">
<%-- body content processing here --%>
</c:forEach>Code language: HTML, XML (xml)

The <c:forTokens> action

The <c:forTokens> action is designed to loop over a string of tokens which are separated by a delimiter. The syntax for the <c:forEach> action is as follows:

<c:forTokens items="stringOfTokens" 
             delims="delimiters"
             var="varName" 
             varStatus="varStatusName"
             begin="begin" 
             end="end" 
             step="step">
<%-- body content processing here --%>
</c:forTokens>Code language: HTML, XML (xml)

You define the string of tokens in the items attribute. Each token in the string of token should be separated by a delimiter. This delimiter is defined in the delims attribute. The var attribute is used to access each token. The other attributes such as begin, end, and step allow you to define which position in the token you want to start with and end with and the step of each iteration. Let’s take a look at an example of using <c:forTokens> action to display information of a person in a table layout.

<%@page contentType="text/html"
        pageEncoding="UTF-8"
        import="com.jsptutorial.*"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core"
          prefix="c" %>

<html>
    <head>
        <title>Looping with c:forTokens</title>
    </head>
    <body>
        <c:set var="infoType"
               value="Jack,Daniel,38,Male,Java Developer" />
        <table border="1">
            <tr>
                <td>First Name</td>
                <td>Last Name</td>
                <td>Age</td>
                <td>Gender</td>
                <td>Position</td>
            </tr>
            <tr>
                <c:forTokens items="${infoType}" delims="," var="info">
                    <td><c:out value="${info}" /></td>
                </c:forTokens>
            </tr>
        </table>
    </body>
</html>Code language: HTML, XML (xml)