JavaServer Pages Standard Tag Library (JSTL)

The JSTL is a collection of custom JSP tags and a supporting expression language that has been designed to simplify writing JSPs. Full details of the JSTL can be found at http://java.sun.com/products/jsp/jstl/. The JSTL is a standard component of J2EE 1.4 but you can also download it for use with J2EE 1.3 compliant servletcontainers.

The JSTL specification defines several tag libraries each supporting a particular functional area and having its own JSP namespace and TLD URI. The areas are summarized in Table 14.1.

Table 14.1. JavaServer Pages Tag Libraries
FunctionNamespace PrefixTLD URL
Core – conditional, iterators and URL actionschttp://java.sun.com/jsp/jstl/core
XML processingxhttp://java.sun.com/jsp/jstl/xml
Internationalization and Formattingfmthttp://java.sun.com/jsp/jstl/fmt
Relational database access and SQLsqlhttp://java.sun.com/jsp/jstl/sql
Functions for manipulating strings and collectionsfnhttp://java.sun.com/jsp/jstl/functions

NOTE

The prefixes are conventional. You do not have to use these prefixes in your JSP, but unless there are good reasons not to (because of established naming conventions for a development project) it is recommended that you restrict the use of these particular prefixes for JSTL. In this way it is clear that you are using JSTL tags and not other custom tags.


To use a tag library on your web page you will need to include a JSP taglib directive defining the Tag Library Descriptor file in the JSP. A TLD file maps the tag names used in the JSP page onto the Java class that implements the tag. You will look at TLDs in more detail later when you write your own custom tag. For now, you will use the TLDs provided with JSTL.

For most of the examples you will see today, you will use the JSTL core library. The following shows how you would declare this in your JSP:

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

In the J2EE RI, the JSTL TLDs and libraries are distributed in the archive appserv-jstl.jar in <J2EE_HOME>/lib/. This archive is automatically loaded into your classpath, so you don't need to add it to your Web application.

JSTL Core Library

The JSTL core library provides a number of tags, or actions, that can be grouped according to their use. Table 14.2 shows some of the core library tags.

Table 14.2. JSTL Core Library Tags.
Action TagDescription
<c:out>Alternative to using EL expressions.
<c:set>Sets the value of a JSP scoped attribute.
<c:remov>Opposite of <c:set>—removes a scoped attribute from the JSP.
<c:catch>Enables you to catch and therefore handle recoverable errors in the JSP.
<c:forEach>Provides a way of iterating over a collection or the equivalent of a for-loop construct.
<c:forTokens>Enables iteration over tokens separated by a given delimiter.
<c:if>Provides the equivalent of a programmatic if statement.
<c:choose> <c:when> <c:otherwise>Together these provide a mutually exclusive conditional list similar to the Java switch statement.
<c:url>Provides URL rewriting for URL links.

The following sections briefly look at some of these actions.

<c:out>

The <c:out> action simply evaluates the string value of its value attribute and outputs the result to the Web page. For example,

<c:out value="${param.name}" />

will output the value of the request parameter called name. You saw on Day 13 an easier way to do this with EL. Therefore, the two following statements are equivalent:

<H1><c:out value="${param.name}" /></H1>
<H1>${param.name}</H1>

The <c:out> action provides a useful default value for when the EL expression evaluates to null. For example, the following takes care of the case when the user does not provide a request parameter:

<c:out value=${param.name} default="Error name not supplied" />

The <c:out> action can be used with pre-JSP 2.0 containers that support tag libraries but not the expression language.

<c:set>

The <c:set> action is used to set a value for a JSP scoped attribute and has a similar role to the <jsp:useBean> tag. For example, an attribute called counter could be incremented as follows:

<c:set var="counter" value="${counter + 1}" />

An attribute is scoped; the scope can be one of the following:

  • page

  • request

  • session

  • application

The default is page scope. If you need the attribute to survive beyond the page, you must specify the scope explicitly, as shown here:

<c:set var="counter" value="${counter + 1}" scope="session" />

NOTE

Attribute names are searched for in each scope in turn. Therefore, a page scope attribute will hide an attribute of the same name in any other scope.


The <c:set> action can also set a property of a JavaBean. For example, presuming you have a JavaBean called customer, you can set a property called login to the value of the request parameter of the same name using the target and property attributes, as follows:

<jsp:useBean id="customer" class="CustomerBean" scope="request" />
<c:set target="${customer}" property="login" value="${param.login}" />

When you use the var attribute, you are setting a scoped variable on the page; when you use a target, this must evaluate to a JavaBean object that has a setter method for the property you want to set.

As you have probably spotted, the <c:set> tag used in this way can replace <jsp:setProperty> actions. Another very useful feature of the target attribute of <c:set> is that you can use it to add elements to a Java Map object. For example, if the CustomerBean example has the following variable declaration:

private HashMap info;

you can add elements to this map with

<c:set target="${customer.info}" property="age" value="22" />
<c:set target="${customer.info}" property="sex" value="male" />

You can use the <forEach> element, described in the following section, to iterate over this map.

<c:forEach>

The <c:forEach> action provides iteration over any type of Java collection object. This tag is extremely useful and, more than any other JSTL element, is likely to replace scripting elements on a JSP. For example, if the CustomerBean has a jobs collection containing all the jobs that customer has advertised, you can create a simple list of those jobs using the following:

<c:forEach var="job" items=${customer.jobs} >
  <P>${job}</P>
</c:forEach>

The body of the element is evaluated repeatedly for every member of the collection specified by the items attribute. The var attribute provides access to each member object in turn.

Another use of <c:forEach> is to access items in a Java Map. With a Map object, the key and value properties provide access to the Map entries. For example, the following generates a table containing the information you previously saw stored in the CustomerBean.info Map:

<TABLE>
  <c:forEach var="item" items="${customer.info}" >
    <TR><TD>${item.key}</TD><TD>${item.value}</TD></TR>
  </c:forEach>
</TABLE>

<c:if>

Not surprisingly, you use <c:if> to add a conditional action to a JSP. For example, the following sets a variable in a nested <c:forEach> to “true” if the customer job (custJob) is found in the collection of agency jobs:

<c:forEach var="agencyJob" items="${agency.jobs}" >
  <c:set var="jobFound" value="false"/>
  <c:forEach var="custJob" items="${customer.jobs}" >
    <c:if test="${custJob == agencyJob}" >
      <c:set var="jobFound" value="true"/>
    </c:if>
  </c:forEach>
  <!-- other processing omitted ... -->
</c:forEach>

Note that the “==” operator in the test behaves as you would hope: it compares the values of the two variables.

There is no <c:else> action, but this functionality can be achieved using the <c:choose> action.

<c:choose>

The <c:choose> action provides a mutually exclusive multi-way conditional statement (like a Java switch statement). Each condition is enclosed in a <c:when> action; with an <c:otherwise> providing a catch-all at the end. You can have a number of <c:when> actions, but only the first to have a test condition that evaluates to true will have its body processed; all others are ignored. Continuing the customer job example, the <c:choose> statement here operates as a if-then-else:

<c:forEach var="custJob" items="${customer.jobs}" >
  <c:set var="jobFound" value="false"/>
  <c:forEach var="agencyJob" items="${agency.jobs}" >
    <c:if test="${custJob == agencyJob}" >
      <c:set var="jobFound" value="true"/>
    </c:if>
  </c:forEach>
  <c:choose>
    <c:when test="${jobFound}" >
      ${custJob} is already registered
    </c:when>
    <c:otherwise>
      Registering ${custJob}
      <!--  code ommitted -->
    </c:otherwise>
  </c:choose>
</c:forEach>

The <c:otherwise> is optional and is only processed if none of the <c:when> actions evaluate to true.

<c:url>

Maintaining session information when cookies are disabled relies on URL rewriting (this subject was covered on Day 12 “Servlets”). Using the <c:url> action, you now have a convenient way of ensuring that your application always uses URL rewriting for any links.

The following example shows how to use the <c:url> in the action attribute of an HTML FORM tag:

<FORM action='<c:url value="/applicant/register" />'>

Other JSTL Libraries

The actions in the JSTL core library provide the general purpose and programming constructs required by all JSPs. The other JSTL libraries provide support for more specialized, but still common, requirements.

Internationalization and Formatting Tag Library

Many Web sites need to provide at least some content in different languages, and some require the entire site to be produced in multiple languages. With static content, the solution is to simply provide copies of the pages in each language. The replication is not a big issue (you have to translate the text in any case), but with dynamic pages maintenance of multiple pages providing the same functionality in different languages would be tedious and error prone.

With the use of resource bundles and the JSTL Internationalization and Formatting library, it is now very simple to internationalize your JSP pages. Resource bundles are collections of text strings accessed by a key, as described in the java.util.ResourceBundle API documentation. You do, of course, have to supply a resource bundle for each language required, each bundle containing equivalent translations of the strings required on the JSP. The resource bundle used is determined by the locale for the JSP. The locale for a Web page is taken from the HTTP request headers supplied by the client but this can be overridden on the JSP page or in the Web Application deployment descriptor. For example the following contrived example sets the locale to en_US to ensure the welcome message is printed in U.S. English:

<fmt:setBundle basename="messages" />
<fmt:setLocale value="en_US" />
<fmt:message key="welcome" />

A number of other actions are provided to format numbers, currencies, and dates according to the client's locale. These actions are also useful for setting consistent formats for data displayed on the JSPs even when internationalization is not required.

SQL Tag Library

As a J2EE exponent, you would probably use a Model View Controller (MVC) architecture for your applications and wrap any database access in an EJB. Nevertheless, for simple Web applications or for testing purposes (checking that your EJB works), the JSTL SQL library provides basic relational database access. As you would expect, the library provides query and update actions as well as transaction control.

Listing 14.1 is a simple HTML form that lists the tables in the Agency database and allows the user to select one.

The JSP that prints out the tables is shown in Listing 14.2. As the name of the table is passed as a request parameter, this JSP can be used to output any table from an SQL database.

Listing 14.1. tableForm.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<HTML>
  <HEAD><TITLE>Agency Tables</TITLE></HEAD>
  <BODY>
    <FORM action='<c:url value="/table" />' >
     Select a table to display:
      <SELECT name="table">
        <OPTION>Applicant
        <OPTION>ApplicantSkill
        <OPTION>Customer
        <OPTION>Job
        <OPTION>JobSKill
        <OPTION>Location
        <OPTION>Matched
        <OPTION>Skill
      </SELECT>
      <P><INPUT type="submit"></P>
    </FORM>
  </BODY>
</HTML>

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

<HTML>
  <HEAD><TITLE>Agency Table: ${param.table}</TITLE> </HEAD>
  <BODY>
    <H1>Data for table ${param.table}</H1>
    <sql:query var="table" sql="SELECT * FROM ${param.table}" />
    <TABLE border="1">
      <TR>
        <c:forEach var="col" items="${table.columnNames}" >
          <TH>${col}</TH>
        </c:forEach>
      </TR>
      <c:forEach var="row" items="${table.rowsByIndex}" >
        <TR>
          <c:forEach var="col" items="${row}" >
            <TD>${col}</TD>
          </c:forEach>
        </TR>
      </c:forEach>
    </TABLE>
  </BODY>
</HTML>

This code is very simple and almost self-explanatory. You obviously need to include the JSTL sql Taglib and give it the sql prefix. The table name is passed to this JSP in the request parameter called table. The SQL query returns a javax.servlet.jsp.jstl.sql.Result object, which has the following properties:

  • rows— An array of java.util.SortedMap with each Map representing a row. The Map key and value properties are used to access the column name and corresponding column value.

  • rowsByIndex— An array of Object[]. Differs from rows in that only the column values are available.

  • columnNames— An array of String containing the column names.

  • rowCount— The number of rows in the result.

Listing 14.2 iterates through all the rows and then through the columns in the row, outputting each row and column value in a table cell.

To view this example, you need to add these two JSPs to a Web application and define a data source called jdbc/Agency for the Agency database. Use the supplied asant build files to build and deploy this example from the Day14/examples directory supplied on the accompanying Web site. To build and deploy use the command:

asant build deploy

Alternatively, use deploytool to deploy the supplied examples.war file in the Day 14/examples/j2ee-ri directory.

The URL to access the tableForm.jsp is

http://localhost:8000/examples/tableForm

XML Library

The XML library provides actions for managing XML documents. This library uses the XPath expression language described on Day 17, “Transforming XML Documents,” in a similar manner to using EL in the core library.

The XML library has a number of actions providing similar functionality to the core library actions but which take XPath expressions. In addition, you can use the <x:transform> action to apply an XSLT stylesheet transformation to an XML document.

Functions Library

Finally, the functions library provides actions for retrieving the length attribute of a collection and manipulating strings. The string manipulation operations provide access to the java.lang.String class functions for converting letter case, searching strings, splitting and joining strings and extracting substrings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.79.65