Skip to content

8. The JSTL tag library

8.0.1. Introduction

Consider the [erreurs.jsp] view, which displays a list of errors:

Image

There are several ways to write such a page. Here, we are only interested in the error display portion. One solution is to use Java code as shown:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>
 
<%
// retrieve data from the model
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs"); 
  String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
 
<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
        <%
          for(int i=0;i<erreurs.size();i++){
            out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
        }//for
      %>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      <%= lienRetourFormulaire %>
    </a>
  </body>
</html>
 

The JSP page retrieves the list of errors from the query (line 8) and displays it using a Java loop (lines 19–23). The page mixes HTML code and Java code, which can be problematic if the page needs to be maintained by a web designer who generally won’t understand Java code. To avoid this mixing, tag libraries are used to bring new capabilities to JSP pages. With the JSTL tag library (Java Standard Tag Library), the previous view becomes the following:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
 
<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      ${lienRetourFormulaire}
    </a>
  </body>
</html>

The tag (line 4)

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

indicates the use of a tag library defined in the file [/WEB-INF/c.tld]. These tags will be used in the page code, prefixed with the letter c (prefix="c"). You can use any prefix of your choice. Here, c stands for [core]. Prefixes allow you to use tag libraries that might have the same names for certain tags. Using the prefix resolves the ambiguity. The new page no longer has Java code in the two places where it previously did:

  • retrieving the template for page [erreurs, lienRetourFormulaire] (removed section)
  • displaying the list of errors (lines 13–15)

The error display loop has been replaced by the following code:


            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
  • The <forEach> tag is used to delimit a loop
  • The ${variable} notation is used to display the value of a variable

The <forEach> tag has two attributes here:

  • items="${errors}" specifies the collection of objects to iterate over. Here, the collection is the errors object. Where is this found? The JSP page searches for an attribute named "errors" successively and in the following order:
    • the [request] object, which represents the request sent by the controller: request.getAttribute("errors")
    • the object [session], which represents the client’s session: session.getAttribute("errors")
    • the object [application], which represents the web application context: application.getAttribute("errors")

The collection designated by the items attribute can take various forms: array, ArrayList, object implementing the List interface, ...

  • var="error" is used to name the current element of the collection being processed. The <forEach> loop will be executed successively for each element of the items collection. Inside the loop, the element of the collection being processed will therefore be referred to here as error.

The notation ${error} inserts the value of the error variable into the text. This variable is not necessarily a string. JSTL uses the error.toString() method to insert the value of the error variable. Instead of the ${error} notation, you can also use the <c:out value="${error}"/> tag.

Returning to our example of displaying errors:

  • The controller will include a ArrayList containing error messages in the request sent to the JSP page, which in turn contains a ArrayList of String objects: request.setAttribute("errors", errors) where errors is the ArrayList;
  • because of the attribute items="${errors}", the JSP page will look for an attribute named errors, successively in the request, the session, and the application. It will find it in the request: request.getAttribute("errors") will return the ArrayList placed in the request by the controller;
  • the "error" variable of the var="error" attribute will therefore refer to the current element of ArrayList, which is a String object. The error.toString() method will insert the value of this String—in this case, an error message—into the HTML stream of the page.

The objects in the collection processed by the <forEach> tag can be more complex than simple strings. Let’s take the example of a JSP page that displays a list of articles:

1
2
3
4
5
6
7
            <c:forEach var="article" items="${listarticles}">
                <tr>
                    <td><c:out value="${article.nom}"/></td>
                    <td><c:out value="${article.prix}"/></td>
                    <td><a href="<c:url value="?action=infos&id=${article.id}"/>">Infos</a></td>
                </tr>
     </c:forEach>

where [listarticles] is a ArrayList of objects of type [Article], which is assumed to be a JavaBean with fields [id, nom, prix, stockActuel, stockMinimum], each of these fields being accompanied by its get and set methods. The [listarticles] object was placed in the request by the controller. The preceding page JSP will retrieve it from the items attribute of the forEach tag. The current object article (var="article") therefore refers to an object of type [Article]. Consider the tag on line 3:

<c:out value="${article.nom}"/>

What does ${article.nom} mean? Actually, various things depending on the nature of the article object. To obtain the value of article.nom, the JSP page will try two things:

  1. article.getNom() - note the spelling getNom to retrieve the name field (JavaBean standard)
  2. article.get("name")

The [article] object can therefore be a bean with a "name" field, or a dictionary with a "name" key.

There are no limits to the hierarchy of the processed object. Thus, the tag

<c:out value="${individu.enfants[1].nom}"/>

allows you to process a [individu] object of the following type:

class Individu{
    private String nom;
    private String prénom;
    private Individu[] enfants;
    // javabean standard methods
    public String getNom(){ return nom;}
    public String getPrénom(){ return prénom;}
    public Individu getEnfants(int i){ return enfants[i];}
}

To obtain the value of ${individu.enfants[1].lastName}, the page JSP will try various methods, including this one, which will succeed:

individu.getEnfants(1).getNom() where individual refers to an object of type Individual.

8.0.2. Install and explore the JSTL library

The explanations provided above will suffice for the application we are interested in, but the JSTL tag library offers other tags besides those presented. To explore them, you can run a tutorial included in the library package.

We will use the JSTL 1.1 implementation of the [Jakarta Taglibs] project, available at Url [http://jakarta.apache.org/taglibs/] (May 2006):

The downloaded ZIP file contains the following:

Image

The two files with the .war extension are web application archives:

  • standard-doc: documentation on JSTL tags
  • standard-examples: examples of tag usage

We will deploy this last application within Tomcat. We start Tomcat via theappropriate option from the [Démarrer] menu, then request the Url [http://localhost:8080] and follow the [Tomcat Manager] link:

Image

We are then presented with an authentication page. We log in as manager/manager or admin/admin, as shown in section 2.3.3.

Image

We are presented with a page listing the applications currently deployed in Tomcat:

Image

We can add a new application using the forms at the bottom of the page:

Image

We use the [Parcourir] button to select a .war file to deploy.

Image

The screenshot does not show it, but we have selected the file [standard-examples.war] from the downloaded distribution JSTL. The [Deploy] button saves and deploys this application within Tomcat.

Image

The [/standard-examples] application has been successfully deployed. We launch it:

Image

Readers are encouraged to follow the various links provided on this page when looking for examples of how to use the JSTL tags.

The [standard-doc] application can be deployed in the same way from the [standard-doc.war] file. It provides access to fairly technical information about the JSTL library. It is of less interest to beginners.

8.0.3. Using JSTL in a web application

In the examples provided with the JSTL 1.2 library, JSP pages begin with the following tag:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

We have already encountered this tag in Section 8.1.1, and we provided a brief explanation:

  • [uri]: URI (Uniform Resource Identifier), where the definitions of the tags used in the page are found. This URI will be used by the web server when the JSP page is translated into Java code to become a servlet. It is also used by web page development tools to verify the correct syntax of the tags used in the page or to provide autocomplete suggestions. When you start typing a tag, a tool familiar with the library can then suggest possible attributes for that tag to the user.
  • [prefix]: prefix that identifies these tags on the page

The uri [http://java.sun.com/jsp/jstl/core] cannot be used if you are not connected to the public internet. In this case, you can place the tag definition file locally. Several such files are provided with the JSTL 1.2 distribution in the [tld] (Tag Language Definition) folder:

Image

JSTL is actually a collection of tag libraries. We will only use the [c.tld] library, known as the "core" library. We will place the [c.tld] file mentioned above in the [WEB-INF] folder of our applications:

Image

and add the following tag to our JSP pages to declare the use of the "core" library:

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

While using tag libraries allows us to avoid putting Java code in the JSP pages, these tags are of course translated into Java code when the JSP page is translated into a Java servlet. They use classes defined in two [jstl.jar, standard.jar] archives found in the [lib] folder of the JSTL distribution:

Image

These two archives are placed in the [WEB-INF/lib] folder of our applications:

Image

We now have the basics to tackle the next version in our example application.