| [ directory ] |
The core set of JSTL tags includes tags that are helpful in most every JSP project. These tags leverage the EL and seek to consolidate equivalent tags implemented by JSP frameworks, container vendors, and individual authors. Core JSTL tags all share the same URI, http://java.sun.com/jstl/core, and can further be segmented based on specific functionality.
Included with the core JSTL tags are a set of general-purpose tags. These tags along with the EL are used for common simple tasks, but the tasks themselves are not built to accomplish a specific larger goal. The tags consist of the out, set, remove, and catch actions.
The out tag takes a JSTL expression and evaluates the result, sending output to the page's current JspWriter object. The tag is helpful as an alternative to the commonly used getProperty action. In cases where a JavaBean is not present, or a developer prefers not to use the bean, the out action provides equivalent functionality. However, in JSP 2.0 out is largely irrelevant; simply putting the equivalent expression directly on the page has exactly the same effect.
The out action has three attributes:
value: The value of the value attribute is the expression to evaluate. The results of the expression are sent to a client using the current page's JspWriter object. The value of the value attribute may be specified at runtime.
escapeXml: The escapeXml attribute specifies if the output of the resulting string should be converted to character entity codes. By default the value is true and the characters <, >, &, ', and " result in <, >, and &, ', and ". The value of the escapeXml attribute may be specified at runtime.
default: The default attribute defines the default value to be used in case the expression fails or results in null.
The out action is very straightforward. Listing 6-1 illustrates the out action being used on a literal.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title><c:out> Action Example</title>
</head>
<body>
<c:out value="${'<tag> , &'}"/>
</body>
</html>
The resulting page is illustrated in Figure 6-1. The literal value is properly escaped so it displays correctly in a browser. Should this not be what is required, the escapeXml attribute could be set to false, such as escapeXml="false".

A good question to ask is why the JSTL out tag is better than simply embedding the expression directly where it is needed. For most practical purposes there is no reason unless you are escaping markup syntaxnamely < and > symbols as < and >. Using only an EL expression in Listing 6-1 would have resulted in <tag> literally appearing in the output instead of <tag> tag, and in the browser rendering, the text would not have appeared.
The set action is a JSTL-friendly version of the setProperty action. The tag is helpful because it evaluates an expression and uses the results to set a value of a JavaBean or a java.util.Map object.
The set action has the following attributes:
value: The value attribute is the expression to be evaluated. This attribute may be a runtime value.
var: The value of the var attribute is the name of an exported variable that is the result of the expression. The type of the variable is whatever the expression evaluates to. This attribute is used when the set action is evaluating a variable to be used by its body content or other components of the JSP.
scope: The scope attribute defines the scope of the object named by the var attribute. Valid values are page, request, session, and application, with page being the default.
target: The target attribute is the name of the target object whose property will be set. The object resulting must be either a JavaBean object with an appropriate setter method or a java.util.Map object. This attribute may be a runtime value.
property: The property attribute is the name of the property to be set of the object specified by the target attribute. This attribute may be a runtime value.
There are two primary ways in which the set action is intended for use. The first use is to set a property of a JavaBean or Map object. In this case the set action uses the value, target and property attributes:
<c:set value="expression" target="target object" property="name of property" />
The second use is to set a scoped variable for use later in the JSP or another resource of the Web Application. In this case the set action would use the value and var attributes, optionally the scope attribute.
<c:set value="value" var="varName"/>
In both cases the value attribute can be omitted in favor of using the tag's body content to replace the expression. In general it is not recommended you design using the set action. As with the setProperty action, the set action embeds code in a JSP that is not desirable. The logic is better abstracted completely out of the JSP as done in the Model 2 design pattern, Chapter 11.
The remove action provides a method of removing a scoped variable. This action is not normally particularly helpful, but it can aid in ensuring that a JSP cleans up any scoped resources it is responsible for. Scoped variables left in session or application scope can be a nuisance and should not be used unless needed.
The remove action has two attributes:
scope: The scope attribute defines the scope to search when removing a variable. If the scope attribute is not defined, the variable is removed by calling the PageContext removeAttribute(varName) method. If the scope attribute is defined, the variable is removed by calling the PageContext removeAttribute(varName, scope) method.
var: The var attribute defines the name of the variable to remove.
Use of the remove action is straightforward; however, it is not recommended you design using the remove action. With a good design and proper use of scoped variables, there should never be a need for a JSP to clean up a scoped resource. This type of logic is not something that is best suited for a JSP, and it should be abstracted completely out of the JSP as done in the Model 2 design pattern, Chapter 11.
The catch action provides a method of error handling for specific parts of a JSP. The feature is helpful as it can prevent a non-critical exception from terminating the execution of a JSP. The catch action works by encapsulating its body content in a try-catch statement.
The catch action only has one attribute, var. The var attribute is the name of the variable in which a caught exception is stored. The type of the variable is the same type as the thrown exception. Should the var attribute not be specified, then the exception is caught and not saved.
Use of the catch action is straightforward. Simply surround problematic code with a catch action to prevent the exception from reaching the page's error handling mechanism. As with the remove and set actions, the catch action should not normally be used. The functionality it provides is much better placed outside of a JSP as dictated by the Model 2 design pattern, Chapter 11. Later on in the chapter a further explanation of the merits of avoiding the remove, set, and catch actions is provided with the JSTL SQL and XML tags.
The core JSTL iteration tags exist to iterate over collections of objects. The tags exist as a good alternative to embedding a Java for, while, or do-while loop via a scriptlet. There are two core iteration tags: forEach and forTokens. The forEach tag is the more commonly used tag because it iterates over a collection of objects. The forTokens tag is used to break a string into tokens and iterate through each of the tokens.
There are good reasons why it would be better to eliminate iterating scriptlets in favor of the JSTL iteration tags. The first and obvious reason is to make it easier to understand what a JSP is doing. Eliminating scriptlets in favor of custom tags increases the amount of markup on a page and reduces the amount of Java code. The end result is a JSP that is easier to read. Consider the JSP in Listing 6-2, which uses an Iterator object and a while loop.
<html>
<head>
<title>Iteration Example</title>
</head>
<body>
<%
Iterator set = (Iterator)request.getAttribute("set");
while (set.hasNext()) { %>
The value is <%= set.next() %>
<% } %>
</body>
</html>
The code is purposely made about as simple as it can get; however, it is still difficult to see what is going on, especially if you are unfamiliar with Java as you would expect of many page-development authors. This is almost always the case, because code appearing in a scripting element is not markup. It is Java. Mixing Java with markup makes it difficult to read either. By using a set of JSP custom tags to replace iteration scriptlets, it is easier to read the page as a whole. Listing 6-3 illustrates what the equivalent page would look like using the JSTL forEach tag.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title>Iteration Example</title>
</head>
<body>
<c:forEach var="item" begin="0" items="${set}">
The value is <c:out value="${item}"/>
</c:forEach>
</body>
</html>
The difference is minor, but it does result in a cleaner page. The markup of a custom tag matches the markup of the surrounding text. The result is that a JSP developer seeing this page for the first time should easily be able to figure out what is going on. The same logic holds true for more realistic and complex examples where there is much more markup and complex code being used in the iteration. In the case of scriptlets the more complex the JSP gets, the harder it is to understand what is going on and the harder it becomes to maintain code.
Another much more important benefit to using the JSTL iteration tags is to enforce clean development of JSP. Certain design patterns, such as Model 2, are built around removing unneeded code from a JSP, usually all the scripting elements. The reason is not to prevent a JSP developer from using iteration, but to prevent a JSP developer from having the freedom to embed arbitrary Java code in scriptlets. Allowing for any type of code can be detrimental to the design of a Web Application. By completely disabling scripting elements and only allowing JSTL iteration tags, it can be ensured a JSP does not have bad code embedded via scripting elements.
The forEach tag provides for iteration over a collection of objects. Currently, the forEach tag supports iteration over an array, java.util.Collection, java.util.Iterator, java.util.Enumeration, or a java.util.Map. In all cases the forEach tag iterates over each primitive, or object, in the collection and exposes it for use by the tag's body.
The forEach tag allows for the following attributes:
var: The var attribute defines the name of the current object, or primitive, exposed to the body of the tag during iteration. Its type depends on the underlying collection. The var attribute must be a static String value.
items: The items attribute defines the collection of items to iterate over. The value may be specified at runtime.
varStatus: The varStatus attribute defines the name of the exported scoped variable that provides the status of the iteration. The object exported is of type javax.servlet.jsp.jstl.LoopTagStatus. The attribute's value must be a static String value and it has nested scope.
begin: The begin attribute is an int value that sets where the iteration should begin. If no value is specified, the iteration index begins at 0, or the first item of the collection. The value of the begin attribute may be a runtime value.
end: The end attribute is an int value that determines inclusively where the iteration is to stop. If no value is specified, the iteration stops after going through the entire collection. The value of the end attribute may be a runtime value.
step: The step attribute is an int value that determines the "step" to use when iterating. Only step items are iterated throughthat is, if step is 2, then every other item is skipped during the iteration. The step value may be a runtime value.
The typical use of the forEach tag is to iterate through a collection passed via the request object. Listing 6-4 illustrates the tag used in a JSP. For more complex uses the iteration may begin, end, or selectively iterate over particular objects. Listing 6-4 illustrates an iteration starting at the second item of the collection and only using the first out of every three items in the collection.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title>Iteration Example</title>
</head>
<body>
<c:forEach var="item" begin="0" items="${set}"
begin="2" step="3">
The value is <%= item %>
</c:forEach>
</body>
</html>
While the iteration tag is helpful in many cases, there is one well-known case that can be problematic. The common task of iterating over a JDBC ResultSet, showing a select number of results at a time, can cause trouble because of caching. Notably many iterations are generated by doing a query on a database, as covered in Chapter 14. When only showing a few select entries from a result, such as items 1 through 20 or 21 through 40, and so on, it is very reasonable to cache the complete query and only show chunks of it as requested. Compared to doing the query each time, this can save a lot of time, memory, and processing power. The problem arises because there are many logical places for caching the information. One would be the JSTL forEach tag, and another would be the database connection that is generating the results. Caching information in more than one place is not desirable, especially if it is a very large result set.
Avoiding the problem is simple. Choose where to cache information and then make sure it is only cached there. Be wary of JSTL forEach tag implementations that attempt to auto-cache for you[3]. Also be wary of any other code which "simplifies" this sort of task for you. While making it easier to develop, you are trading the amount of control you have over optimizations such as caches.
[3] The JSTL reference implementation "featured" auto-caching with the forEach tag. This caused problems, especially when used with the JSTL SQL tags and a JDBC driver that also auto-caches results. Large results would take up twice as much memory.
The forTokens tag parses a String into tokens based on a given delimiter. All of the tokens are then iterated over, the same as the forEach tag. All of the attributes of the forEach tag are shared by the forTokens tag. One new attribute is additionally allowed: delims. The delims attribute defines the value used to delimit tokens in the source String. Any String value may be used as a delimiter. The delims attribute value may also be a runtime value.
Additionally the items attribute takes on a new meaning with the forTokens tag. Instead of defining a collection to iterate through, the items attribute is the String to parse.
In use the forTokens tag is identical to the forEach tag but with the delims attribute specifying a token delimiter. Listing 6-5 provides an example of the forTokens tag iterating through a literal String value.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title>Iteration Example</title>
</head>
<body>
<c:forTokens var="item" delims="~" items="token1~token2~token3">
The value is <c:out value="${item}" />
</c:forTokens>
</body>
</html>
JSTL core conditional tags support simple statements such as a Java if and switch. The tags are a replacement for scriptlets commonly needed to accomplish the same functionality. Like the iteration tags, by using the conditional tags a cleaner markup-orientated syntax can be maintained in favor of scripting elements. There are two main groups of conditional tags: if and choose. The if tag mimics a simple Java if statement, while the choose tag mimics a Java switch or if/else statement.
The if tag allows the conditional execution of its body depending on the value of a test attribute. Should the test result in true, the contents of the tag's body are evaluated. Should the test result in false, the contents of the tag's body are skipped.
The if action has the following attributes:
test: The test attribute is the condition for if the body content should be shown or not. A literal true or false value may be used, but an expression is most helpful.
var: The var attribute is an optional attribute that defines the name of a scoped variable. A scoped variable defined by the var attribute contains the results of the test attribute and can be further used by the JSP.
scope: The scope attribute defines the scope of the var attribute. Valid values for the scope attribute are page, request, session, and application.
Sometimes the if tag's functionality is best abstracted using a good design pattern, but there are cases where the if tag can be very convenient. A good example is reminding a user he or she needs to log in. A site's main page may be freely available to the public, but the rest of the site requires a user to have logged on. To remind a user they need to log on, a simple conditional can be used on the main page. Listing 6-6 illustrates how this could be done, assuming after logging in a session-scoped object, user, is set.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title><c:if> Action Example</title>
</head>
<body>
<c:if test="${user == null}">
<form>
Name: <input name="name">
Pass: <input name="pass">
</form>
</c:if>
<c:if test="${user != null}">
Welcome ${user.name}
</c:if>
<!--
Rest of main page here...
-->
</body>
</html>
The page has two simple checks: one for if the user is logged on and one for if he or she is not. Should the user be logged on, a welcome message is displayed.
<c:if test="${user != null}">
Welcome ${user.name}
</c:if>
Should a user not be logged on, a log-on form is displayed.
<c:if test="${user == null}">
<form>
Name: <input name="name">
Pass: <input name="pass">
</form>
</c:if>
In both cases the full contents of the page will be shown. If the contents were restricted, then the if action would not be the best of choices. Instead two completely separate JSP should be shown, depending on if the user needs to log in or not.
The choose tag performs conditional block execution of sub when tags. It renders the body of the first when tag whose test condition evaluates to true. If none of the test conditions evaluate to true, then the body of an otherwise tag is evaluated. If no otherwise tag is present, nothing happens.
The choose and otherwise tags have no attributes. The when tag has one attribute, test. The test attribute is an expression that determines if the condition of a when tag is true. If true, the body content of the when tag is evaluated.
Use of the choose tag is straightforward and the tag is as helpful as the if tag. In some situations it makes sense to move the functionality completely out of the JSP, but there are circumstances where the choose tag is a convenient solution. For example, you can author the equivalent of Listing 6-6 by using the choose, when, and otherwise tags that are shown in Listing 6-7.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title><c:choose> Action Example</title>
</head>
<body>
<c:choose>
<c:when test="${user == null}">
<form>
Name: <input name="name">
Pass: <input name="pass">
</form>
</c:when>
<c:otherwise>
Welcome ${user.name}"
</c:otherwise>
</c:choose>
<!--
Rest of main page here...
-->
</body>
</html>
JSP provide weak support for URL manipulation. The JSP include action only allows for inclusion of resources in the Web Application. External pages or resources can only be included via a custom solution. JSP also manage state via cookies with a fall-back mechanism of URL rewriting. If a client does not support cookies, URL rewriting must be used, but there is no way to automatically rewrite all URLs. The JSTL provides a solution to both of these problems with a few custom tags.
The import tag provides all of the functionality of the include action but also allows for inclusion of absolute URLs. For example, using the import tag allows for inclusion of content from a different Web site or an FTP server. Content retrieved by the import tag can also be made available in a few different ways. By default the included information is directly sent to the page's current JspWriter object, but optional attributes may be used to specify a scoped variable or a Reader object where the content should be made available.
The import tag has the following attributes:
url: The value of the url attribute is the URL to import. Valid values include both relative and absolute URLs. The value may be specified by a runtime value.
context: The context attribute can be used to provide the name of a context when accessing a relative URL resource that belongs to a foreign context. The value may be specified by a runtime value. A foreign context is another Web Application that is executing on the same Web server. This value should be used if the URL is relative to that named foreign context. Note that this is the equivalent of a request dispatch across Web Application boundaries and may not work on particular containers due to security or other restrictions.
var: The var attribute can be used to name a scoped variable to contain the resource's content. The type of the variable is String.
scope: The scope attribute defines the scope of a variable named by the var attribute. Valid values are page, request, session, and application.
charEncoding: The charEncoding attribute can be used to specify the character encoding of the content at the input resource. By default it is assumed the standard, ISO-8859-1, encoding is used.
varReader: The varReader attribute is available to create a Reader object for use by content in the import tag's body. The value of the varReader attribute is the name of the scoped variable; the type of the variable is java.io.Reader.
There are two ways to use the import tag. The first is to import local or remote content and send it directly to the client. In this case the url attribute is required to specify the URL to include, optionally with the context and charEncoding attributes.
<c:import url="url" />
The results of such an include depend on the resource being included. If, for example, the following JSP was used:
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %> <c:import url="http://www.jspbook.com" />
The result would be identical to the code generated by browsing to http://www.jspbook.com: relative style sheets and images wouldn't work, but the code would be the same.
The second method of using the import action is to import the contents of the URL to a scoped variable or to a Reader object. In this case the import action would be used with the url attribute and either the varReader or var attributes, optionally the context, scope, and charEncoding attributes. For instance, to show the source code of a local or remote Web page, you could combine the import and out actions as shown in Listing 6-8.
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<html>
<head>
<title><c:import> Action Example</title>
</head>
<body>
Here is the source code of the main page:
<pre>
<c:import url="welcome.html" var="value"/>
<c:out value="${value}"/>
</pre>
</body>
</html>
The result of Listing 6-8 is a page that shows the code sent back from a response to http://127.0.0.1/jspbook/welcome.html. Note the code in the case of HTML; the source code is the same as the result. However, if Listing 6-8 is used to request a JSP, it shows the response, not the source code. Figure 6-2 shows a browser rendering of the results.

The param tag complements the import tag by allowing proper URL request parameters to be specified with a URL. Commonly, a URL request parameter is hard coded to the end of a URLfor example, test.jsp?name=value. However, this practice does not always work because a URL must be encoded as defined in RFC 2396, http://www.ietf.org/rfc/rfc2396.txt. Without proper encoding, the URL parameters may not be correctly sent with a request. To ensure proper encoding, the JSTL provides the param tag.
The param tag has two attributes:
name: The name attribute specifies the name of the URL parameter.
value: The value attribute specifies the value of the URL parameter.
The param tag is used as a child of the import tag to set URL parameters.
The url tag is a method the JSTL provides to automatically encode URLs with session information and parameters. As a container is required to try and keep a session associated with a client, cookies[4] are used and work perfectly fine unless a client purposely disables them or does not support them. In the case where a client does not support cookies, session information needs to be directly encoded with a URL. A JSP developer can do this manually by replacing all URLs with a call to the HttpServletResponse encodeURL() method. For instance, the following anchor tag:
<a href="index.jsp">Book Site</a>
would be changed to:
<a href='<%= response.encodeURL("index.jsp")%>'>
Book Site</a>
The practice works; the JSTL url action is just an alternative method of writing the call to the encodeURL() method. The only real advantage the url tag provides is proper URL encoding, including any parameters specified by children param tags.
The url tag has the following attributes:
value: The value attribute is used to provide the URL to be processed.
context: The context attribute defines the name of the context when specifying a relative URL resource of a foreign context.
var: The var attribute can be used to export the rewritten URL to a scoped variable. The value of the var variable is the processed URL. The type of the variable is String. The variable's scope depends on the scope attribute.
scope: The scope attribute determines the scope of the object named by the var attribute. Valid values are page, request, session, and application.
The url tag only changes relative URLs to avoid accidentally exposing session informationthat is, /index.jsp would be encoded, but http://www.jspbook.com would not.
For most practical purposes the url tag works but is just plain awkward. It does provide a method of encoding a URL with parameters, but do not think you always need to properly encode URLs. Preserving session information in case a client does not use cookies is helpful, but can be safely ignored unless a Web Application relies on always keeping session state. Should keeping session be mandated, then use the encodeURL() method or the url tag as needed. Alternatively, another cleaner solution to providing URL encoding support is to abstract the formatting via a multi-client design as covered in Chapter 13.
The redirect tag complements the URL manipulating tags by providing a tag that properly encodes a client-side redirection. The functionality of the redirect tag is equivalent to calling the HttpServletResponse sendRedirect() method. The tag may have child param tags used to define parameters.
The redirect tag allows the following parameters:
url: The url attribute specifies the relative or absolute URL the client should be redirected to.
context: The context attribute specifies the name of the context to use when the url attribute refers to a foreign context.
Using the redirect tag is straightforward; however, you are not encouraged to design around using it. The functionality provided by the redirect tag is best abstracted out of a JSP as shown in Chapter 11.
| [ directory ] |