Overview

This document provides a high level overview of the JSP™ Standard Tag Library (JSTL) as it stands for EA3 (Early Access release 3). If you have a strong opinion on the topic — positive (you really like it), or constructive (we messed up some parts and you have some constructive comments for improvements) — we'll be happy to hear from you at jsr052-comments@sun.com. All comments will be read but we cannot guaranteee personal replies to all of them.

Make sure you read this document first, then check out the jstl-examples web application in the release (once you have installed it on your web container following the instructions in the Getting Started document). This will help you get a good feel for what JSTL is all about. Then browse the other docs to get all the details, and finally give JSTL a ride in your own prototype web application. You should use JSTL only in prototype webapps because this is Early Access and things may/will change as we gather feedback and make adjustments. Thanks for your help making JSTL an awesome standard tag library...

Design Philosophy

JSP tag libraries help provide a clean separation between the business logic and the presentation layer of web applications. By keeping the programming logic out of JSP pages, web designers are now empowered to develop sophisticated JSP pages without having to resort to the scripting language associated with their JSP pages (usually the Java programming language).

The base design philosophy in JSTL is therefore to provide page authors with a script free environment. EA1 defines the foundation elements to make this possible.

Multiple TLDs

A Tag Library is a collection of actions that encapsulate functionality to be used from within a JSP page. JSTL includes a wide variety of actions that naturally fit into discrete functional areas. This is why JSTL, altough a single standard tag library, is exposed via multiple TLDs to clearly show the functional areas it covers, as well as to give each one of them their own namespace. The table below lists these functional areas along with their URI. The table also shows the prefixes used in our documentation and examples (although web applications can use any prefix they want).

Funtional Area URI Prefix Example
Core http://java.sun.com/jstl/ea/core
c
<c:tagname ...>
XML processing http://java.sun.com/jstl/ea/xml
x
<x:tagname ...>
I18N capable formatting http://java.sun.com/jstl/ea/fmt
fmt
<fmt:tagname ...>
Database access (SQL) http://java.sun.com/jstl/ea/sql
sql
<sql:tagname ...>


Expression Language Support

A key contribution of JSTL is the integration of an Expression Language (EL). An EL leverages the fact that JSP scoped attributes are the privileged way to communicate information from the business logic to the JSP pages. It makes it possible to easily access application data and manipulate it in simple ways without having to use scriptlets or request-time expression values.

For example, this conditional tag tests whether the country of a customer is the USA.

  <c:if test="$customer.address.country == 'USA'">
    ...

  </c:if>

There were quite a few issues involved with the support of an Expression Language within JSTL given the constraint that it had to work without requiring any change to the JSP spec. In order to be able to support both the scripting (rtexprvalues) and the EL (elexprvalues) worlds, we had to come up with the concept of twin tag libraries: one that supports the expression language, and one that supports request time expression values. Our assumption is that people will mostly use the EL-based tag libraries, while it is still possible for hard core scripting page authors to use JSTL with rtexprvalues (provides benefits for type safety and performance) via the request-time based tag libraries (their URI simply has the "-rt" suffix appended).

It is a hard task for the Expert Group to decide on a specific EL without first getting the general feeling from the community. This is why JSTL currently does not define a specific EL, but provides mechanisms for experimentation with a variety of ELs. Tell us what you feel is important for that EL, and feel free to implement one that others can experiment with. The goal is to select a single EL once the JSTL spec is ready for Community Review.

Early Access contains several candidate Expression Languages. One of them is an implementation subset of ECMAScript (JavaScript) and is the one used by default. Please check EcmaScript as an Expression Language for JSTL.

Tag Collaboration

Tags usually collaborate with their environment in implicit and/or explicit ways. Implicit collaboration is done via a well defined interface that allows nested tags to work seamleasly with the ancestor tag exposing that interface. The JSTL iterator tags support this mode of collaboration. Explicit collaboration happens when a tag explicitely exposes information to its environment. Traditionally, this has been done by exposing a scripting variable (with a JSP scoped attribute providing the actual object). Because JSTL supports an expression language, the need for scripting variables is significantly reduced. This is why all the JSTL tags expose information only as JSP scoped attributes (no scripting variable exposed). A bold move, we agree, but we feel this is the proper design decision to support script-free JSP pages.

The convention is to use the name "var" for any tag attribute that exports information about the tag. For example, an iterator tag exposes the current item of the collection it is iterating over in the following way:

  <c:forEach var="customer" items="$customers">
    ...

  </c:forEach>

It is important to note that a name different than "id" was selected to stress the fact that a variable is exposed (actually a JSP scoped attribute), but not a scripting variable (which is normally the case when using an attribute named "id").

The convention also establishes the attribute "scope" to set the scope (page, request, session, application) of the JSP scoped attribute.

In situations where a tag exposes more than one piece of information, the name "var" is used for the primary piece of information being exported, and an appropriate name is selected for any other secondary piece of information exposed (e.g. an iteration current status information is exported by the foreach tag via attribute status.)

The fact that JSTL tags do not expose scripting variables would make it hard to collaborate with other tags whose data must be passed as rtexprvalues. To that effect, tag <declare> allows to declare a scripting variable to be associated with the JSP scoped attribute of the same name.

Tag Overloading

In JSTL, we try as much as possible to avoid too much "overloading" of a tag; i.e. tags with lots of attributes that can do just about anything. Rather, we privilege a larger number of tags with well focused behavior.


JSTL EA3— Quick Reference

Core Actions

Expression Language Support Tags
Element Sample usage

<expr>
value default

Like <%= ... %> but for EL expressions.

<c:set var="city"         value="$customer.address.city"/>

<c:set var="customerFmt" scope="request">
  <font color=red>
   
<c:expr value="$customer"/>
  </font>
</c:set>

<set>
var value scope

Sets the result of an expression evaluation in a scoped attribute.

<c:set var="city"         value="$customer.address.city"/>

<c:set var="customerFmt" scope="request">
  <font color=red>
    <c:expr value="$customer"/>
  </font>
</c:set>

<declare>
id
type

Declares a scripting variable, initially defined by an existing scoped attribute of the same name. The type of the variable defaults to java.lang.Object but can be modified by using the 'type' attribute.

<c:declare id="customer" type="acme.Customer"/>


Iterator Tags
Element Sample usage

<forEach>
var items status
begin end step

The basic iteration tag, accepting many different collection types and supporting subsetting and other functionality

<c:forEach var="customer" items="$customers">
  ...
</c:forEach>

<c:forEach var="customer" items="$customers"
            status="status"
            begin="100" end="200" step="2">

  ...
</c:forEach>

<forTokens>
var items status
begin end step

delims

Iterates over tokens, separated by the supplied delimiters

<c:forTokens var="token" items="blue|white|red"
              delims="|">

  ...
</c:forTokens>
interface IteratorTag allows developers to write custom iteration tags by implementing the IteratorTag interface.
interface IteratorTagStatus Provides an interface for objects representing the current status of an iteration. JSTL 1.0 provides a mechanism for IteratorTags to return information about the current index of the iteration and convenience methods to determine whether or not the current round is either the first or last in the iteration. It also lets authors use the status object to obtain information about the iteration range, step, and current object.
abstract class IteratorTagSupport Since most iteration tags will behave identically with respect to actual iterative behavior, JSTL 1.0 provides this base support class to facilitate implementation. Many iteration tags will extend this and merely implement the hasNext() and next() methods to provide contents for the handler to iterate over.

Conditional Tags
Element Sample usage

<if>
test var

Simple conditional tag, which evalutes its body if the supplied condition is true and optionally exposes a Boolean page attribute representing the evaluation of this condition.

<c:if test="$customer.address.country == 'USA'">
  ...
</c:if>

<c:if var="isUsCustomer"
  test="$customer.address.country == 'USA'"/>

<choose>
<when>
  test
<otherwise>

Simple conditional tag that establishes a context for mutually exclusive conditional operations, marked by <when> and <otherwise>.

<c:choose>
  <when test="...">
    ...
  </when>

  <when test="...">
    ...
  </when>

  ...
  <otherwise>
    ...
  </otherwise>

</c:choose>

abstract class ConditionalTagSupport Abstract class that facilitates implementation of conditional tags -- specifically, tags in the style of <if>.


Import Tags
Element Sample usage

<import>
url var varReader charEncoding context

Action for a simple, generic way to access URL based resources. Extends <jsp:include> to support foreign contexts and absolute URLs, as well as to export an object for explicit collaboration with process/transformation tags (avoiding unnecessary buffering).

<c:import url="ftp://ftp.acme.com/README"/>

<c:import url="/xml/doc.xml" varReader="in"/>
<acme:process in="$in"
/>

<param>
name value encode

Sub-element to specify request parameters for the enclosing <import>. The name and value of the parameter are url encoded (unless encode is false).

<c:import url="/exec/register">
  <c:param name="id" value="foo"/>
</c:import>

<urlEncode>
value var

URL encoding.

<a href="http://acme.com/register
   ?name=<c:urlEncode value='$name'/>"/>

XML Actions

XML Core Tags
Element Sample usage
<parse>
var domVar source filter

Parses an XML and saves its internal representation into the JSP scoped attribute specified by "var" (or "domVar").
<c:import url="http://acme.com/athletes?country=ethiopia" var="xml"/>
<x:parse source="$xml" var="athletes"/>

<expr>
select

Evaluates the given XPath expression and outputs its text value.

<x:expr select="$ath/name"/>

<set>
var select

Evaluates the given XPath expression and saves the result into the JSP scoped attribute specified by "var".

<x:set
  select="$athletes/athlete[country=$request:country]"   var="athletesOfCountry"/>

XML Control Flow Tags
Element Sample usage
<forEach>
 select var

Evaluates the given XPath expression and iterates over the result, setting the context node to each element in the iteration.
<x:forEach select="$doc//author">
  <x:valueOf select="@name">
</x:forEach>

<if>
 select

Simple conditional tag, which evalutes its body if the supplied Xpath expression evaluates to true (as if by a call to the XPath "boolean" function).

<x:if select="$customer/[location='UK']">
  UK based
</x:if>

<choose>
<when>
 select

<otherwise>


Simple conditional tag that establishes a context for mutually exclusive conditional operations, marked by <when> and <otherwise>.

<x:choose>
  <x:when select="...">
    ...
  </x:when>

  <x:when select="...">
    ...
  </x:when>

  ...
  <x:otherwise>
    ...
  </x:otherwise>

</x:choose>

XML Transformation Tags
Element Sample usage

<transform>
source xslt transformer result var

Applies a transformation to an XML document given a specific XSLT stylesheet or a transformer object.

<c:import url="/xml/employees.xml" var="xml"/>
<c:import url="/xslt/customerList.xsl" var="xslt"/>
<x:xslt source="$xml" xslt="$xslt"/>

<param>
name value

Sub-element to specify request parameters for the enclosing <transform>.


<x:transform source="$xml" xslt="$xslt">
<x:param name="foo" value="foo-value"/>
</x:transform>

 

<transformer>
var xslt

Creates a "transformer" object for more efficient transformations that use the same XSLT stylesheet.

<c:import url="/xslt/style.xsl" var="xslt"/>
<x:transformer xslt="$xslt" var="transformer"/>
...
<x:transform source="$xml" transformer="$transformer" /> ... <x:transform source="$xml2" transformer="$transformer" />

I18N & Formatting actions

I18N Tags
Element Sample usage
<locale>
value variant scope

Establishes the locale specified by the value attribute for the variant given by the variant attribute.

<fmt:locale value="en-US" variant="UNIX"/>
<timeZone>
value var scope

Establishes the time zone given by the value attribute.

<fmt:timeZone value="America/Los_Angeles">
  <fmt:formatDate type="time"/>
</fmt:timeZone>
<bundle>
basename prefix var scope

Loads the resource bundle whose base name is specified by the basename attribute, and optionally exposes it in the named scoped attribute.

<fmt:bundle basename="Greetings" var="greetingBundle"/>
<message>
key bundle var scope

Fetches the localized message corresponding to the key specified by the key attribute from the resource bundle given by the bundle attribute, and performs parametric replacement on the retrieved message using the argument values supplied via <messageArg> subtags

<fmt:message key="Welcome" bundle="$greetingBundle"/>
<messageFormat>
value var scope

Performs parametric replacement on the pattern specified by the value attribute using the argument values supplied via <messageArg> subtags

<fmt:messageFormat value="$priceMsg">
  <fmt:messageArg value="$priceArg"/>
</fmt:messageFormat>
<messageArg>
value

Supplies the argument specified by the value attribute  (if present) or the tag body to its parent <message> action for parametric replacement

<fmt:message key="Welcome" bundle="$greetingBundle"> 
  <fmt:messageArg value="$dateArg"/>
</fmt:message>
<formatNumber>
value type pattern var scope

Formats the given numeric value as a number, currency, or percentage using the locale's predefined or the specified (customized) formatting pattern 

<fmt:formatNumber value="9876543.21" type="currency"/>
<parseNumber>
value type pattern var scope

Parses the given numeric string using the locale's default or the specified (customized) formatting pattern

<fmt:parseNumber value="$num" var="parsed"/>
<formatDate>
value type dateStyle timeStyle pattern timeZone var scope

Formats the given date using the locale's predefined or the specified (customized) formatting pattern 

<fmt:formatDate timeStyle="long" dateStyle="long"/>
<parseDate>
value type pattern var scope

Parses the given date string using the locale's default or the specified (customized) formatting pattern

<fmt:parseDate value="May 22, 2001 4:05:53 PM PDT" var="parsed"/>
<exception>
value bundle stackTrace

Displays the exception given by the value attribute (or the error page's exception if no value attribute is given) in its localized form

<fmt:exception bundle="$errorMessages"/>

SQL actions

SQL Actions
Action Sample usage

<sql:query>

<sql:query var="varName"
          sql="sqlQuery"
          [dataSource=dataSourceSpec]
          [maxRows="maxRows"]
          [startRow="startRow"]/>

<sql:query var="varName"
   
      [sql="sqlQuery"]
          [dataSource=dataSourceSpec]
          [maxRows="maxRows"]
          [startRow="startRow"]/>

  ... optional query statement ...
  ... optional <sql:param> actions ...
</sql:query>

General purpose action for performing SQL queries on a database and gettting back a single result set containing rows of data.

<sql:query var="customers"
             dataSource="$dataSource">
   SELECT * FROM employees
   WHERE country = 'China'
   ORDER BY lastname
</sql:query>

<sql:update>

<sql:update var="varName"
          sql="sqlUpdate"
          [dataSource=dataSourceSpec]/>

<sql:update var="varName"
   
      [sql="sqlUpdate"]
          [dataSource=dataSourceSpec]>
  ... optional query statement ...
  ... optional <sql:param> actions ...
</sql:update>

General purpose action for "updates"; i.e. statements that update the database (insert, update, delete) and return nothing or a single integer.

<sql:update>
  UPDATE account
  SET BALANCE = ?
  WHERE accountNo = ?
  <sql:param
     value="$balance">
  <sql:param
     value="$accountNo">
</sql:update>

<sql:transaction>

<sql:transaction
    [dataSource=dataSourceSpec]
    [transactionIsolation="transactionIsolationLevel"]>
  ... <sql:query> and <sql:update> statements ...
</sql:transaction>

 

<sql:driver>

<sql:driver var="varName"
           [driver="driverClassName"]
           [url="url"]
           [user="user"] />

Facilitates the setup of a DataSource object around a JDBC driver for prototype/simple applications.

 

<sql:param>

<sql:param value="parameterValue"/>

<sql:param>
  ... parameter value ...
</sql:param>

Subtag of SQLExecutionTag actions such as <sql:query> and <sql:update> to set the values of parameter markers ('?') specified in the SQL statement.

 

<sql:query> result related interfaces

public interface Result
public interface ResultMetaData
public interface Row
public interface ColumnMetaData

public
interface Column

 

interface SQLExecutionTag

Identifies a tag handler that can accept parameter values from nested tag handlers.

 

Tag Library Validators

Tag Library Validators
EA1 comes with two TagLibraryValidators (TLVs), which are classes that ensure pages meet particular criteria before they can run.
Tag Library Validator Sample Usage
JsptlCoreTLV

(Nothing special is required to use the Core TLV. This validator simply does its best to ensure that JSTL's tags are used correctly, reporting useful error messages when it can.)

ScriptFreeTLV The following directive on a JSP page invokes the ScriptFreeTLV validator to make sure that no scripting elements appear on the page:
<%@ taglib prefix="scriptfree"
    uri="http://jakarta.apache.org/taglibs/jsptl/scriptfree" %>

Expression Language Selection

Expression Language Selection

Temporary mechanisms that allow for runtime pluggability of expression-language evaluators. This allows for experimentation with expression languages and is not expected to remain in the final release of JSTL 1.0.

Element Sample usage

context parameter

Establishes the default Expression Language used by the web application.

<context-param>
  <param-name>
   
javax.servlet.jstl.ExpressionEvaluatorClass
  </param-name>
  <param-value>
    org.apache.taglibs.jstl.lang.spel.Evaluator
  </param-value>
</context-param>

<expressionLanguage>

Change the current Expression Language

<c:expressionLanguage
  
evaluator="org.apache.taglibs.jstl.lang.jpath.Evaluator">
  ...
</c:expressionLanguage>