An Introduction to JSTL

by Sue Spielman

Have you heard about the JSTL but aren't quite sure of how to make the best use of it? The JSTL: Practical Guide for JSP Programmers covers everything you need to know to get started and become productive using the JSP Standard Tag Library.  The Practical Guide series continues to be packed with information for real developers and is written in a straightforward and easy-to-use manner. 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.

The following sections are excerpted from various chapters within the JSTL: Practical Guide for Java Programmers. The selected sections  should give you a taste of what you can learn from the book.  Sue Spielman will be in the JSP forum the week of Sept 30  answering questions and will also be giving away complimentary copies of the JSTL: Practical Guide for JSP Programmers.

Introduction

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 http://jcp.org/jsr/detail/52.jsp . 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:

These libraries are defined by the Tag Library Descriptor 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. As touched on briefly in the first chapter, 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 doing application data manipulation for the page author. 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 the test 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 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 like:

<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 (like book ,for example) with the EL, it is the same thing as if you had done PageContext.findAttribute(identifier ).The identifier itself can reside in any of the known JSP scopes. This includes page ,request ,session ,or application 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, and applicationScope. All of these xScope 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 and headerValues.

The param and header objects are Maps that map the parameter or header name to a String .This is similar to doing a ServletRequest.getParameter(String name) or ServletRequest.getHeader(String name).The paramValues and headerValues are Maps that map parameter and header names to a String[] of all values for that parameter or header. Again, this is as if you had made ServletRequest.getParameterValues(String name) or ServletRequest.getHeaders(String) calls.

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

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

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

Automatic Type Conversion

The automatic type conversion is a very convenient feature of the EL in that a full set of coercion 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, I'm including the coercion rules from the JSTL 1.0 specification in JSTL Reference section so that you can review them if you want.

Let's look at Example 3.1.If we have a variable called myInteger 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 the String 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 of 9) at that point an exception will be thrown. Having automatic type conversions can save unnecessary exceptions from happening.

Example 3.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:

javax.servlet.ServletException:An error occurred while  evaluating custom action attribute "value" with value "${myInteger *2}":An exception occured 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 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 3.2.

Example 3.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:

Let's look at each functional section in the Core tag library a bit more closely.

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 current JspWriter .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 XML entity values that are used for encoding the characters are shown in Table 4.1. Therefore it's possible also to use this encoding capability to encode any HTML, like <br>, so that the angle brackets appear correctly. This capability is controlled by the escapeXml attribute. It defaults to true .

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="com.mk.jstl.bookInfo"%>

<%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 called myData .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 4.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 the esacpeXml set 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 4.1:EscapeXML sample.

Working with the Internationalization and Formatting Actions

More than likely, the application you are developing today will have to be internationalized tomorrow. Wouldn't it be great if the effort required to internationalize your application could be reduced to zero? Well okay, that might be too optimistic to hope for since anyone who has developed applications for international use knows there is always something that needs to be tweaked. Luckily, the internationalization and formatting actions provided in the JSTL are a comprehensive set of actions that can be used to minimize the headaches of having to internationalize your application. These actions come under the functionality of the I18N umbrella. I18N, which refers to the 18 letters between the I and the N in internationalization ,is a common acronym used when talking about internationalization features. It is also common to use the term L10N, for localization. In this chapter, we'll explore these internationalization actions. All of the actions related to I18N are contained in the custom tag library with the URI http://java.sun.com/jstl/fmt and are frequently accessed by using the fmt prefix x.

The I18N functional area can be broken down into two main areas:

1. Locale and resource bundles that include such actions as:

2. Formatting for numbers, dates, and currency, which includes such actions as:

To address both of these functional areas, let's first take a cursory look at what pieces are involved in creating international applications. Then we'll look at how these pieces can be put to work using the various actions available in the JSTL.

First,the <fmt:message>Action

Before we start talking about the various actions available in the I18N,let's introduce the <fmt:message>action. If you really wanted to do the bare-bones amount of work necessary to build an internationalized application,<fmt:message>is the only action that you'll need to consider. The <fmt:message>action takes advantage of the LocalizationContext (which we talk about in the next section).By using the <fmt:message>,you can output values from your resource bundles as simply as:

<fmt:message key="welcome"/>

The appropriate resource bundle will be used to look up the key "welcome" and the translated string will be provided. This is about as easy as it gets to incorporate international support into your application. The <fmt:message>action also supports parameterized content, also called parametric replacement. For example, you can provide variables that will be used within the string used by the key attribute. Say we want to personalize our welcome page and pass the name of a user so that we can welcome them. To do this, we use the <fmt:param> subtag. We will talk about this in more detail later in this chapter, but as a quick example, so that you are familiar with the format, the action might look like:

<fmt:message key="welcome">

<fmt:param value="${userNameString}"/>

</fmt:message>

In this example, we would be accessing a variable already set, called userNameString , that would then be used as a parameter to the message. If we were accessing the English version of the resource bundle,Welcome Sue would appear in the JspWriter . Now, with the basics of the <fmt:message>under your belt, let's take a more in-depth look at how the I18N actions work.

Author Note: Chapter 6 -  Working with the Internationalization and Formatting Actions continues by going into great detail on how to work with Locales, resource bundles, and all of the I18N standard actions.

Using the SQL Actions

The JSTL includes a number of actions that provide a mechanism for interacting with databases. The previous sentence should, at a very minimum, send up a red flag in your architectural visions. One might ask, "Do I really want to be able to perform SQL actions such as queries, updates, and transactions from my JSP? Isn't that business logic that belongs in the model? The answer is yes. Yes, yes, yes. To follow a Model-View-

Controller (MVC) architecture, which is the predominant design pattern used in building web applications today, you definitely want to keep your model information in your business logic. This means that you don't want it in your JSPs. Why then are these actions even provided in the JSTL? Good question and one that I've discussed with various members of the JSR-53 expert group. The reason is the "C" or community in the Java Community Process (JCP). The community has asked for it, the community has gotten it.

Many feel that for prototyping, small-scale, and/or very simple applications, or if you just don't have the engineering staff to implement a full MVC model, then the SQL actions might prove useful. While I can (barely) see the point being made for use of the SQL actions for prototyping or small-scale applications, I can't ever validate the argument that you just don't have the time to implement an MVC model correctly. If that is the one and only reason why you are choosing to use the SQL actions, then I suggest that you investigate using such frameworks as Struts which is part of the Jakarta projects and can be found at http://jakarta.apache.org/struts/index.html . Struts is an MVC framework that can be learned quickly and will provide a much cleaner architecture than having Model information located throughout your JSPs. For a complete discussion on Struts along with a sample application, refer to The Struts Framework:Practical Guide for Java Programmers, another title in the Morgan Kaufmann Practical Guide series.

If you are careful about how you code your SQL actions, it should be easy enough to pull out the code and put it into classes that represent the Model interaction at a later point. I am not going to go into the various design patterns that can be applied for doing business or integration tier access. But if you consider using the SQL actions in your application, it would be wise at least to familiarize yourself with such common patterns as Transfer Objects, JDBC for Reading, Data Transfer Object (DTO) Factory, Data Transfer Hashmap,and Data Transfer Rowset. Doing so may help you avoid embedding the business logic/data access into your JSPs so deeply that you are left with a tangled mess.

With that said, I don't consider it an architectural flaw to have the SQL actions included in the JSTL. However, I do consider it an architectural flaw to use them in your application development. It is up to the page author and application architect to make sure that the design patterns are being adhered to correctly, if not for the maintenance issue of the application then for the practice of good engineering. However, since these actions are included in the JSTL,I must make sure you understand them and their features so that you can make an informed decision.

The JSTL SQL actions provide functionality that allows for:

What all of the SQL actions have in common is that they work against a specific data source.

Let's examine how the data source is set up and configured. We'll then go through the other configuration settings as well as the available interfaces. Then we'll a look at how to use the actions in situations where their use would be appropriate.

The Available <SQL>Actions

There are six actions provided in this tag library:

Author note: I hope that you've found these brief excerpts to be helpful and applicable to your development.

Sue Spielman is president and senior consulting engineer, of Switchback Software LLC, http://www.switchbacksoftware.com . Switchback Software specializes in architecture/design and development of enterprise business and web applications. Sue is the author of ‘The Struts Framework: Practical Guide for Java Programmers', ‘JSTL: Practical Guide for JSP Programmers' and ‘The Web Conferencing Book'. Sue can also be found speaking at various technical conferences around the country. You can reach her at sspielman at switchbacksoftware.com