Home

JSP and Beyond

a pragmatic primer on building web-based solutions with Java technologies


Developing with Tags – JSTL / EL

The Java Server Pages Standard Tag Library (JSTL) enables us to bring commonly needed web actions and components out of scriptlets and into easy to use tag libraries. JSTL is generally used in conjunction with another “tag” style markup called expression language, or EL, to build non-scriptlet JSP solutions. Since JSTL and EL are standards, they are supported by all containers that are JSP 1.2 and beyond compliant. This makes them portable between different application servers, and they are guaranteed to run on any application server that supports the JSP 1.2 specification and beyond.

That being said, it is important not to go overboard with this technology when developing applications. JSTL is very powerful and can even connect to databases using certain tags, but that is not always the best way to include that type of functionality. To get the most out of JSP, you should keep the majority of logic- and settings-related-markup out of your JSP pages and in reusable components (i.e. beans or other classes) whenever possible; and then use JSTL and EL to focus on displaying the contents of those objects and not retrieving or manipulating the data.

Java Server Pages Standard Tag Library (JSTL)
JSTL consists of a few libraries. Each one of these libraries provides slightly different capabilities as highlighted below.

The Java Server Pages Standard Tag Library (JSTL) enables us to bring commonly needed web actions and components out of scriptlets and into easy to use tag libraries. JSTL is generally used in conjunction with another “tag” style markup called expression language, or EL, to build non-scriptlet JSP solutions. Since JSTL and EL are standards, they are supported by all containers that are JSP 1.2 and beyond compliant. This makes them portable between different application servers, and they are guaranteed to run on any application server that supports the JSP 1.2 specification and beyond.

That being said, it is important not to go overboard with this technology when developing applications. JSTL is very powerful and can even connect to databases using certain tags, but that is not always the best way to include that type of functionality. To get the most out of JSP, you should keep the majority of logic- and settings-related-markup out of your JSP pages and in reusable components (i.e. beans or other classes) whenever possible; and then use JSTL and EL to focus on displaying the contents of those objects and not retrieving or manipulating the data.

Java Server Pages Standard Tag Library (JSTL)
JSTL consists of a few libraries. Each one of these libraries provides slightly different capabilities as highlighted below.

Tag Library
Core (c) Variable support, conditionals, URL management
XML (x) Core, Flow control, Transformation
Internationalization (fmt) Locale, Message formatting, Number and date formatting
Database (sql) SQL query and update
Function (fn) Collection length, String manipulation

This chapter will focus on the Core library, since once you understand how the libraries can be used it is relatively trivial to implement the one that will meet your needs.

Accessing JSTL
In order to use JSTL you need to make sure to reference the specific tag set within JSTL that you would like to use in the body of the JSP.

<%– Core –%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core” %>

<%– I18N Formatting –%>
<%@ taglib uri=”/WEB-INF/tld/fmt-rt.tld” prefix=”fmt_rt” %>

<%– SQL –%>
<%@ taglib uri=”/WEB-INF/tld/sql-rt.tld” prefix=”sql_rt” %>

<%– XML –%>
<%@ taglib uri=”/WEB-INF/tld/x-rt.tld” prefix=”x_rt” %>

As “core” would indicate, the core library contains some of the most used tags from the JSTL. Below is a listing of the core types along with samples.

Working with Variables
Using JSTL it is possible to set and remove variables within the JSP page. The following example set the accountHistory variable with the value from a JavaBean called “account” using the set tag.

<c:set var=”accountHistory” value=”${account.history}”>

Expression
JSTL has the ability to display object attribute and variable information very easily. The example below renders the username from the bean called “customer” using the out tag.

<jsp:useBean id=”user” class=”com.jspbeyond.user”/>

Welcome <c:out value=”${user.displayname}” />!

Iteration
One of the biggest challenges that I have encountered with iteration is the understanding of exactly what objects can be used to iterate through. java.util.Collection, java.util.Map, java.util.Iterator, java.util.Enumeration, an array of object instances and javax.Servlet.jsp.jstl.sql.Result can all be used as the object that an iteration can be based on. In the code sample below, assume that you have an array called “customerList” containing a list of beans representing customers.

<table>
<c:forEach items=”${customerList}” var=”customer”>
<tr><td>
<c:out value=”${customer.name}” />
</td></tr>
<tr><td>
<c:out value=”${customer.contactInfo}” />
</td></tr>
</c:forEach>
</table>

With the above example, you are able to merge your dynamic elements with the HTML template. This allows maximum control over the look and feel of the page that is displayed to users and lets developers and designers focus on their respective disciplines.

Conditionals
JSTL provides an elegant way to conditionally display content. The following block uses an “if” conditional.

<c:if test=”${user.loggedin}”>
<tr>
<td>
<c:out value=”${user.password}”/>
</td>
</tr>
</c:if>

The code block below uses a “choose” conditional. The choose conditional is best applied when various matches are possible.

<c:choose>
<c:when test=”${user.team == ‘Management’}”>
Project is on time!
</c:when>
<c:when test=”${user.team == ‘Developer’}”>
Great job coding!
</c:when>
<c:otherwise>
Not sure why you are here!
</c:otherwise>
</c:choose>

Beyond the examples above, you will see that during form validation, JSTL conditionals can be very helpful.

URL Management
JSTL provides some innovative ways to interact with page flow and incorporating content from other JSPs. This is done through three tags: “import”, “redirect” and “url”. For each one of the tags, it is also possible to specify parameters that are passed along with the request.

The following example highlights the use of the import tag.

<!– This example gets content from welcomeheader.jsp and injects it into the page –>
<c:import url=”welcomeheader.jsp” />

<!– This example requests a URL with the parameter “myparam” set to 1 –>
<c:import url=”mypagewithparameter.jsp”>
<c:param name=”myparam” value=”1” />
</c:import>

The redirect tag works much the same way as the import tag, allowing you to pass along arguments with the request in the URL.

<c:redirect url=”accountView.jsp”>
<c:param name=”id” value=”${id}”/>
</c:redirect>

When you need to ensure that a URL is properly formatted, the “url” tag does a nice job of handling things such as automatic encoding.

<c:url value=”listproducts.jsp”>
<c:param name=”category” value=”outdoor camping gear”/>
</c:url>

Exception Handling with Try / Catch
Just at with any code that is written, it is always good to make sure that you can handle errors gracefully. JSTL provides a nice way to do this directly in the JSP as follows.

<c:catch var=”testexception”>
<!– Do something REALLY bad here to cause an error –>
</c:catch>
<c:out value=”${ testexception.message}”/>

Expression Language (EL)
Expression language provides an easy way to access information from a variety of objects directly within the body of a JSP, and send the resulting information into an attribute for a JavaBean or JSTL element. EL can get information from implicit objects and/or custom objects and variables that you may have in scope.

Looking at many of the examples in the prior section, you can see that there were instances where we accessed data in a format like ${somedata.here}. This is EL. The close relationship between JSTL and EL is why many people lump them into a single category, although they are ultimately different technologies.

That being said, some of the best, most common uses, would be leveraging EL Implicit Objects directly in the JSP. For instance, the following section of EL retrieves the query string variable called username.

How are you ${param.username}?

Beyond accessing information from objects, EL also has the ability to leverage operators. This allows blocks of code to execute conditionally when combined with JSTL as illustrated below.

<c:if test=”${user.age >= 16}”>
You can drive!
</c:if>

Operators like ==, !=, <, >, >= or <= can all be used to make decisions with EL. For example, using the above operators lets you perform conditional evaluations directly in your JSPs

Is a one the same as a two? ${1==2}

Tags in Action - Examples
The following two JSPs are from our reference application, and demonstrate how much cleaner the template (HTML) markup can be when scriptlets are replaced with JSTL, keeping any serious Java code out of the presentation layer. CustomerList-Scriptlet.jsp shows a version of a page using scriptlets and CustomerList-JSTL.jsp shows a cleaned up version using JSTL.

CustomerList-Scriptlet.jsp

<%@page import=”java.sql.*” %>

<html>
<head>
<title>JSP and Beyond - Customer List - Scriptlet Example</title>
</head>
<body>

<h1>Customer List - Scriptlet Example</h1>

<%
Connection conn = null;

// Reference the JDBC driver
Class.forName(”com.mysql.jdbc.Driver”).newInstance();
conn = DriverManager.getConnection(”jdbc:mysql:///PortletCRM”,”root”, “ax355b”);
Statement stmt = conn.createStatement();

// Set the SQL query
ResultSet rs = stmt.executeQuery(”SELECT * FROM tblCustomer ORDER BY CustomerName”);

// Start our table tag
out.println(”<table width=\”100%\” border=\”1\”>”);
out.println(”<tr><td colspan=\”4\”>Customer</td></tr>”);

while(rs.next())
{
out.println(”<tr><td>”);

// Render a link that will let this page show notes
out.println(”<a href=\”" + request.getRequestURI() + “?shownotes=” + rs.getString(”CustomerID”) + “\”>show notes</a>”);

// Render the Customer name
out.println(rs.getString(”CustomerName”) + “</td>”);

// Render the customer type
//out.println(rs.getString(”CustomerType”) + “</td><td>”);

// Render edit link
out.println(”<td><a href=\”CustomerEdit-Scriptlet.jsp?CustomerID=” + rs.getString(”CustomerID”) + “\”>edit</td>”);

// Render add note link
out.println(”<td><a href=\”NoteAdd-Scriptlet.jsp?CustomerID=” + rs.getString(”CustomerID”) + “\”>add note</td>”);

// Render delete customer link
out.println(”<td><a href=\”CustomerDelete-Scriptlet.jsp?CustomerID=” + rs.getString(”CustomerID”) + “\”>delete</td>”);

out.println(”</tr>”);

// Check to see if show details is enabled
if (request.getParameter(”shownotes”) != null)
{
if (request.getParameter(”shownotes”).equals(rs.getString(”CustomerID”)) | request.getParameter(”shownotes”).equals(”all”))
{

Statement stmtDetails = conn.createStatement();

// Set the SQL query
ResultSet rsDetails = stmtDetails.executeQuery(”SELECT * FROM tblNote WHERE CustomerID = ” + rs.getString(”CustomerID”));

while(rsDetails.next())
{
// Render the customer type
out.println(”<tr><td colspan=\”4\”>” + rsDetails.getString(”Note”) + ” - <a href=\”NoteDelete-Scriptlet.jsp?NoteID=” + rsDetails.getString(”NoteID”) + “\”>delete</a></td></tr>”);
}

rsDetails.close();
stmtDetails.close();
}
}
}

// Close our table
out.println(”</table>”);

// Close the connections to database objects to free resources
stmt.close();
conn.close();
%>

<br>
<a href=”CustomerAdd-Scriptlet.jsp”>Add a New Customer</a> | <a href=”CustomerList-Scriptlet.jsp?shownotes=all”>Show all Notes</a>

</body>
</html>

CustomerList-JSTL.jsp

<%– Let the system know that we are using JSTL and load the proper prefixs –%>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core_rt” %>
<%@ taglib prefix=”sql” uri=”http://java.sun.com/jstl/sql_rt” %>

<html>
<head>
<title>JSP and Beyond - Customer List - JSTL Example</title>
</head>
<body>

<h1>Customer List - JSTL Example</h1>

<%– Let the system know what datasource we will speak with –%>
<sql:setDataSource var=”dataSource” url=”jdbc:mysql://localhost/PortletCRM”
driver=”com.mysql.jdbc.Driver” user=”root” password=”ax355b” />

<sql:query var=”queryResults” dataSource=”${dataSource}”>
<%– Place our SQL query here within the XML tag “sql:query” –%>
SELECT * FROM tblCustomer ORDER BY CustomerName
</sql:query>

<table width=”100%” border=”1″>
<tr>
<td colspan=”4″>Customer</td>
</tr>

<%– Start a loop through the results from the SQL query and mix it with HTML –%>
<c:forEach var=”row” items=”${queryResults.rows}”>
<tr>
<%– Notice how with each “row” object we can access the column name by specifying it after the “row” object –%>
<td><a href=”CustomerList-JSTL.jsp?shownotes=<c:out value=”${row.CustomerID}”/>”>show notes</a> <c:out value=”${row.CustomerName}”/></td>
<td><a href=”CustomerEdit-JSTL.jsp?CustomerID=<c:out value=”${row.CustomerID}”/>”>edit</a></td>
<td><a href=”NoteAdd-JSTL.jsp?CustomerID=<c:out value=”${row.CustomerID}”/>”>add note</a></td>
<td><a href=”CustomerDelete-JSTL.jsp?CustomerID=<c:out value=”${row.CustomerID}”/>”>delete</a></td>
</tr>
<c:if test=”${(row.CustomerID) == (param.shownotes) or (param.shownotes) == 0}”>
<sql:query var=”queryDetailResults” dataSource=”${dataSource}”>
<%– Place our SQL query here within the XML tag “sql:query” –%>
SELECT * FROM tblNote WHERE CustomerID = ?
<sql:param value=”${row.CustomerID}” />
</sql:query>
<c:forEach var=”rowDetail” items=”${queryDetailResults.rows}”>
<tr><td colspan=”4″><c:out value=”${rowDetail.Note}”/> - <a href=”NoteDelete-JSTL.jsp?NoteID=<c:out value=”${rowDetail.NoteID}”/>”>delete</a></td></tr>
</c:forEach>
</c:if>
</c:forEach>
</table>

<br>
<a href=”CustomerAdd-JSTL.jsp”>Add a New Customer</a> | <a href=”CustomerList-JSTL.jsp?shownotes=0″>Show all Notes</a>

</body>
</html>

Not only is the above code easier to read, the code block is also much shorter. It is easy to see how JSTL can make code much easier to read and maintain.