Practical JSTL, Part 1 Blog


    If you have heard about the JSP Standard Tag Library (JSTL) but aren't quite sure of how to make the best u se of it, this first of two excerpts from the JSTL: Practical Guide for JSP Programmers provides an introduction to the technology. The JSTL allows page authors to make use of easy-to-learn, easy-to-use standard ac tions for common ways we deal with presentation. The book has just been released, and comes with free download of all code examples used throughout. Each standard action is covered with a detailed explanation and includes a code sample, so you can start using the JSTL immediately.

    This will be a two-part series. This set of excerpts from the book offers a functional overview and takes a look at the expression language and some of the actions available in the Core tag library. Next time, we'll take a look at what the standard actions provided in the other tag libraries.


    JSTL is the JSP Standard Tag Library. The JSTL came about under JSR-52 of the Java Community Process (JCP). The specification can be found at the JCP site. JSR-52 covers the creation of a standard tag library for JavaServer Pages and allows this library to be available to all compliant JSP containers. These tag libraries provide a wide range of custom action functionality that most JSP authors have found themselves in need of in the past. Having a defined specification for how the functionality is implemented means that a page author can learn these custom actions once and then use and reuse them on all future products on all application containers that support the specification. Using the JSTL will not only make your JSPs more readable and maintainable, but will allow you to concentrate on good design and implementation practices in your pages. We can finally take the "custom" out of custom action and replace it with "standard." No more creating your own iteration action for the tenth time. Additionally, your favorite Integrated Development Environment (IDE) that supports JSP authoring will now support these standard actions and can assist the JSP page author in rapid development.

    Functional Overview

    The JSTL encapsulates common functionality that a typical JSP author would encounter. This set of common functionality has come about through the input of the various members of the expert group. Since this expert group has a good cross-section of JSP authors and users, the actions provided in the JSTL should suit a wide audience. The JSTL is a set of custom actions that is based on the JSP 1.2 and servlet 2.3 specifications. While the JSTL is commonly referred to as a single tag library, it is actually composed of four separate tag libraries:

    • Core
    • XML manipulation
    • SQL
    • Internationalization and formatting

    These libraries are defined by the Tag Library Descriptor (TLD) files. Using separate TLDs to expose the tags, the functionality for each set of actions is apparent and makes more sense. Using separate TLDs also allows each library to have its own namespace. To sum up for now, the layout of the JSTL is straightforward.

    The overriding theme throughout the JSTL is simplifying the life of the page author. The page author is the person who builds the JSP pages. There has always been a need (although not a requirement) that the page authors have some understanding of a programming language (usually Java) in order to create complex pages. This dilemma is what has hampered the true role separation between the JSP page author and the Java programmer. Using the tags provided in the JSTL, we are closer to reaching that clean division of labor. The functional areas in the JSTL help page authors identify what type of functionality they need, and where they can find it.

    Using the Expression Language

    Before we dive into the various functional areas in the JSTL, we should start with the expression language. This is one of the most important features of the JSTL and is a prominent feature of the JSP 2.0 specification. The expression language (EL) allows for a much simpler syntax for the page author to manipulate application data. Currently the EL in the JSTL can only be used with tag attribute values, primarily in actions that reside in the Core tag library. It is possible to use the EL within template text if you are working with the JSP 2.0 specification. Expressions in template text are not supported if you are using JSTL 1.0 with JSP 1.2.

    What it means to use EL in attributes can be shown in the following example:

    <c:if test="${book.orderQuantity > book.inStock}"> The book <c:out value="${book.title}"/> is currently out of stock. </c:if>

    Using the <c:if> conditional tag (which we'll talk about in detail shortly), we can use the EL in thetest attribute to determine if we can order a book that is currently in stock. If the book is not in stock, we can access the book object by using the EL and assigning that to the value attribute. Anyone who has worked with JSPs before can certainly appreciate the ease of use and coding simplification made possible with the EL. If you are working with JSP 2.0, this sample could also be written using the expression in the template text:

    <c:if test="${book.orderQuantity >book.inStock}"> The book ${book.title} is currently out of stock. </c:if>

    Keep in mind that when using an identifier (likebook, for example) with the EL, it is the same thing as if you had donePageContext.findAttribute(identifier). The identifier itself can reside in any of the known JSP scopes. This includespage, request, session, orapplication scope. If the identifier isn't found in any scope, then a null value is returned.

    Implicit Objects Available in the EL

    There are quite a few implicit objects exposed through the EL. These objects allow for access to any variables that are held in the particular JSP scopes. Objects include pageScope,requestScope, sessionScope, andapplicationScope. All of thesexScope objects are Maps that map the respective scope attribute names to their values. Using the implicit objects param and paramValues, it is also possible to access HTTP request parameters. This holds true for request header information, as well as for using the implicit objects header andheaderValues.

    The param and header objects areMaps that map the parameter or header name to aString. This is similar to doing aServletRequest.getParameter(String name) orServletRequest.getHeader(String name). TheparamValues and headerValues areMaps that map parameter and header names to aString[] of all values for that parameter or header. Again, this is as if you had madeServletRequest.getParameterValues(String name) orServletRequest.getHeaders(String) calls.

    The initParam gives access to context initialization parameters, while cookie exposes cookies received in the request. The implicit objectpageContext gives access to all properties associated with the PageContext of a JSP page, such as theHttpServletRequest, ServletContext, andHttpSession objects and their properties.

    Let's look at a couple of samples to drive the usage of the objects home:

    • ${pageContext.request.servletPath} will return the servlet path obtained from the HttpServletRequest.

    • ${sessionScope.loginId} will return the session-scoped attribute named LoginId, ornull if the attribute is not found.

    • ${param.bookId} will return the Stringvalue of the bookId parameter, or null if it is not found.

    • ${paramValues.bookId} will return theString[] containing all values of thebookId parameter, or null if it is not found. Using paramValues is particularly useful if you have a form with checkboxes or if, for some other reason, a parameter might have multiple values, as with a multiselect box.

    The EL operations are necessary to handle data manipulations. All of the Java standard and common operators are available. Functionality is included in the EL for relational, arithmetic, and logical operators.

    Automatic Type Conversion

    Automatic type conversion is a very convenient feature of the EL, in that a full set of coercions between various object and primitive types is supported. Coercion means that the page author isn't responsible for converting parameters into the appropriate objects or primitives. The JSTL defines appropriate conversions and default values. For example, a String parameter from a request will be coerced to the appropriate object or primitive.

    If we are dealing with A, which is an item or object, the coercion rules supplied by the JSTL will be applied for each given type. These coercions are done under the covers for you by the implementation, but it is always a good idea to understand how (and in what order) the rules are being applied. For this reason, the coercion rules from the JSTL 1.0 specification are included in the book's JSTL Reference section so that you can review them if you want.

    Let's look at Example 1. If we have a variable calledmyInteger and want to use the value in an expression as a number, we simply declare a variable with the value using<c:set>. If a parameter that represents the month is passed in the request as a String, the value of the month variable will be correct because theString will be coerced to the correct type when used. If the value of the parameter does not parse correctly to a number -- say, the value is September instead of9 -- then an exception will be thrown. Having automatic type conversions can save unnecessary exceptions from happening.

    Example 1. Performing a Coercion

    <c:set var="myInteger"value="${param.month}"/> <p> The value of myInteger is:<c:out value="${myInteger}"/> Perform a multiplication operation to show that the type is correct: <c:out value="${myInteger *2}"/>

    If the coercion is not possible, the exception might look something like this:

    javax.servlet.ServletException: An error occurred while evaluating custom action attribute "value" with value "${myInteger *2}": An exception occurred trying to convert String "September" to type "java.lang.Double"(null)

    Keep in mind that it's possible to use<c:catch> to prevent a complete exception stack trace from being displayed to the user. The page author can handle an unexpected value more in a user-friendly way, perhaps informing the user of the type of data that is expected, or providing a sample of the format of data required by the user. A more graceful handling of an error is shown in Example 2.

    Example 2. Friendly Handling of a Coercion Error

    <c:catch var="coercionError"> The value of myInteger is:<c:out value="${myInteger}"/> Perform a multiplication operation to show that the type is correct:<c:out value="${myInteger *2}"/> </c:catch> <c:if test="${not empty coercionError}"> <b>The value of month is supposed to be a number.</b> Here 's more information on the error: <br><font color="#FF0000"><c:out value="${coercionError}"/> </font> </c:if>

    Working with the Core Actions

    The set of tags that are available in the Core tag library come into play for probably most anything you will be doing in your JSPs. Let's walk through code samples to see how we use each of the tags provided in this library.

    The Core area comprises four distinct functional sections:

    • General-purpose actions that are used to manipulate the scoped variables that might be found within a JSP. These general-purpose actions also encompass error handling.
    • Conditional actions used for doing conditional processing within a JSP.
    • Iterator actions that make it easy to iterate through collections of objects.
    • URL-related actions for dealing with URL resources in a JSP.

    Writing Output to the JspWriter

    There are four general-purpose tags. The<c:out> tag is probably the tag that you will see the most. It is used to output to the currentJspWriter. This is similar to using the JSP expression<%=scripting language expression %> to write dynamic data to the client.

    The value to be written to the JspWriter is specified as a value attribute. You can use expressions in the value attribute. This allows for the resulting evaluation to be sent to the JspWriter. The <c:out>tag can perform XML character-entity encoding for<, >, &,", and '. This means that a< will be automatically encoded to&lt;. The book includes a table of the XML entity values that are used for encoding the characters. Therefore, it's possible also to use this encoding capability to encode any HTML, such as <br>, so that the angle brackets appear correctly. This capability is controlled by theescapeXml attribute. It defaults totrue.

    It should be obvious that:

    The title of the book you just purchased is <c:out value="${sessionScope.bookInfo.title}">

    is much easier to read (and write) than:

    <%@page import=""%> <%BookInfo bookInfo =(BookInfo)session.getAttribute" ("bookInfo"); %> The title of the book you just purchased is <%=bookInfo.getTitle()%>

    In another example, we might want to output some data values that have been stored in a scoped variable calledmyData. The value of myData is"<b>I love to ride my bicycle</b>". There are HTML tags included in the string that we want to make sure are rendered correctly, with the string bolded. To ensure that the data is displayed to the user correctly, we would use:

    <c:out value=${myData}escapeXml="false"/>

    With escapeXml set to false, our users see the correct display with the text bolded.

    Otherwise, they just see the characters <b>displayed with the text, as shown in Figure 1.

    The two displays are shown as they would appear if you were to view the source of the resulting file in your browser. The first output is using the default value of escapeXml, while the second output shows the result of using escapeXmlset to false. With escapeXml defaulting to true:

    &lt;b&gt;I love to ride my bicycle&lt;/b&gt;

    With escapeXml set to false:

    <b>I love to ride my bicycle</b>

    Figure 1
    Figure 1. escapeXML sample

    I hope that you've found these brief excerpts to be helpful and applicable to your development. In the next excerpt, we'll get a taste for many of the standard actions provided in the International and Formatting, XML, and SQL tag libraries.