I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

JavaServer Pages Tag Library (JSTL) is a set of tags that can be used for implementing some common operations such as looping, conditional formatting, and others.

In this tutorial, we’ll be discussing how to setup JSTL and how to use its numerous tags.

2. Setup

To enable JSTL features, we’d have to add the library to our project. For a Maven project, we add the dependency in pom.xml file:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

With the library added to our project, the final setup will be to add the core JSTL tag and any other tags’ namespace file to our JSP using the taglib directive like this:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Next, we’ll take a look at these tags which are broadly grouped into five categories.

3. Core Tags

JSTL core tag library contains tags for performing basic operations such as printing values, variables declaration, exception handling, performing iterations, and declaring conditional statements among others.

Let’s have a look at core tags.

3.1. The <c:out> Tag

<c:out> is used for displaying values contained in variables or the result of an implicit expression.

It has three attributes: value, default, and escapeXML. The escapeXML attribute outputs raw XML tags contained in the value attribute or its enclosure.

An example of <c:out> tag will be:

<c:out value="${pageTitle}"/>

3.2. The <c:set> Tag

The <c:set> tag is used for declaring scoped variables in JSP. We can also declare the name of the variable and its value in the var and value attributes respectively.

An example will be of the form:

<c:set value="JSTL Core Tags Example" var="pageTitle"/>

3.3. The <c:remove> Tag

The <c:remove> tag removes scoped variables which is equivalent to assigning null to a variable. It takes var and scope attribute with scope having a default value of all scopes.

Below, we show an example usage of <c:remove> tag:

<c:remove var="pageTitle"/>

3.4. The <c:catch> Tag

The <c:catch> tag catches any exception thrown within its enclosure. If the exception is thrown, it’s value is stored in the var attribute of this tag.

Typical usage could look like:

<c:catch var ="exceptionThrown">
    <% int x = Integer.valueOf("a");%>
</c:catch>

And to check if the exception is thrown, we use the <c:if> tag as shown below:

<c:if test = "${exceptionThrown != null}">
    <p>The exception is : ${exceptionThrown} <br />
      There is an exception: ${exceptionThrown.message}
    </p>
</c:if>

3.5. The <c:if> Tag

The <c:if> is a conditional tag that displays or executes it’s enclosed scriptlets only when its test attribute evaluates to true. The result of the evaluation can be stored in its var attribute.

3.6. <c:choose>, <c:when> and <c:otherwise> Tags

The <c:choose> is a parent tag that is used in performing switch-like or if-else expressions. It has two subtags; <c:when> and <c:otherwise> which represent if/else-if and else respectively.

<c:when> takes a test attribute which holds the expression to be evaluated. Below, we show an example usage of these tags:

<c:set value="<%= Calendar.getInstance().get(Calendar.SECOND)%>" var="seconds"/>
<c:choose>
    <c:when test="${seconds le 30 }">
        <c:out value="${seconds} is less than 30"/>
    </c:when>
    <c:when test="${seconds eq 30 }">
        <c:out value="${seconds} is equal to 30"/>
    </c:when>
    <c:otherwise>
        <c:out value="${seconds} is greater than 30"/>
    </c:otherwise>
</c:choose>

3.7. The <c:import> Tag

The <c:import> tag handles fetching and exposing content from absolute or relative URLs.

We can use the url and var attributes to hold the URL, and the content fetched from the URL respectively. For example, we could import contents from a URL by:

<c:import var = "data" url = "http://www.example.com"/>

3.8. The <c:forEach> Tag

The <c:forEach> tag is similar to Java’s for, while or do-while syntax. The items attribute holds the list of items to be iterated over, while begin and end attributes hold the starting and ending index respectively (zero indexing).

<c:forEach> tag also has a step attribute that controls the size of index increment after each iteration. Below, we show an example usage:

<c:forEach var = "i" items="1,4,5,6,7,8,9">
    Item <c:out value = "No. ${i}"/><p>
</c:forEach>

3.9. The <c:forTokens> Tag

The <c:forTokens> tag is used for splitting a String into tokens and iterating through them.

Similar to <c:forEach> tag, it has an items attribute and an additional delim attribute which is the delimiter for the String like this:

<c:forTokens 
  items = "Patrick:Wilson:Ibrahima:Chris" 
  delims = ":" var = "name">
    <c:out value = "Name: ${name}"/><p>
</c:forTokens>

3.10. <c:url> and <c:param> Tags

The <c:url> tag is useful for formatting a URL with proper request encoding. the formatted URL is stored in the var attribute.

<c:url> tag also has a <c:param> subtag which is used for specifying URL parameters. We show an example below:

<c:url value = "/core_tags" var = "myURL">
    <c:param name = "parameter_1" value = "1234"/>
    <c:param name = "parameter_2" value = "abcd"/>
</c:url>

3.11. The <c:redirect> Tag

The <c:redirect> tag performs a URL rewrite and redirects the user to the page specified in its url attribute. A typical use case will look like this:

<c:redirect url="/core_tags"/>

4. Formatting Tags

JSTL formatting tag library provides a convenient way for formatting text, numbers, dates, times and other variables for better display.

JSTL formatting tags can also be used to enhance the internationalization of a website.

Before using these formatting tags, we’ve to add the taglib to our JSP:

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

Let’s identify the various formatting tags and how they can be used.

4.1. The <fmt:formatDate> Tag

The <fmt:formatDate> tag is useful in formatting dates or time. The value attribute holds the date to be formatted, and the type attribute takes one of three values; date, time or both.

<fmt:formatDate> also has a pattern attribute where we can specify the desired formatting pattern. Below is an example of one of the patterns:

<c:set var="now" value="<%= new java.util.Date()%>"/>
<fmt:formatDate type="time" value="${now}"/>

4.2. The <fmt:parseDate> Tag

The <fmt:parseDate> tag is similar to <fmt:formatDate> tag.

The difference is that with <fmt:parseDate> tag we can specify the formatting pattern that the underlying date parser should expect the date value to be in.

We can parse dates:

<c:set var="today" value="28-03-2018"/>
<fmt:parseDate value="${today}" var="parsedDate" pattern="dd-MM-yyyy"/>

4.3. The <fmt:formatNumber> Tag

The <fmt:formatNumber> tag handles rendering of numbers in a specific pattern or precision which can be one of number, currency or percentage as specified in its type attribute. An example usage of <fmt:formatNumber> would be:

<c:set var="fee" value="35050.1067"/>
<fmt:formatNumber value="${fee}" type="currency"/>

4.4. The <fmt:parseNumber> Tag

The <fmt:parseNumber> tag is similar to <fmt:formatNumber> tag. The difference is that with <fmt:parseNumber> tag we can specify the formatting pattern that the underlying number parser should expect the number to be in.

We could use this like:

<fmt:parseNumber var="i" type="number" value="${fee}"/>

4.5. The <fmt:bundle> Tag

The <fmt:bundle> tag is a parent tag for <fmt:message> tag. <fmt:bundle> makes the bundle specified in its basename attribute to the enclosed <fmt:message> tags.

<fmt:bundle> tag is useful for enabling internationalization as we can specify locale-specific objects. Typical usage will be of the form:

<fmt:bundle basename="com.baeldung.jstl.bundles.CustomMessage" prefix="verb.">
    <fmt:message key="go"/><br/>
    <fmt:message key="come"/><br/>
    <fmt:message key="sit"/><br/>
    <fmt:message key="stand"/><br/>
</fmt:bundle>

4.6. The <fmt:setBundle> Tag

The <fmt:setBundle> tag is used for loading a resource bundle within JSP and making it available through the entire page. The loaded resource bundle is stored in the var attribute of the <fmt:setBundle> tag. We can set bundle by:

<fmt:setBundle basename="com.baeldung.jstl.bundles.CustomMessage" var="lang"/>

4.7. The <fmt:setLocale> Tag

The <fmt:setLocale> tag is used to set the locale for the sections in JSP placed after it’s declaration. Typically we will set this by:

<fmt:setLocale value="fr_FR"/>

fr_FR represents the locale which is French in this case.

4.8. The <fmt:timeZone> Tag

The <fmt:timeZone> tag is a parent tag that specifies the time zone to be used by any time formatting or parsing actions by tags in its enclosure.

This time zone parameter is supplied by its value attribute. An example usage is shown below:

<fmt:timeZone value="${zone}">
    <fmt:formatDate value="${now}" timeZone="${zn}" 
      type="both"/>
</fmt:timeZone>

4.9. The <fmt:setTimeZone> Tag

The <fmt:setTimeZone> tag can be used to copy the time zone specified in its value attribute to a scoped variable specified in its var attribute. We define this by:

<fmt:setTimeZone value="GMT+9"/>

4.10. The <fmt:message> Tag

The <fmt:message> tag is used to display internationalization message. The unique identifier for the message to be retrieved should be passed to its key attribute.

A specific bundle to lookup the message which can also be specified through the bundle attribute.

This may look like this:

<fmt:setBundle basename = "com.baeldung.jstl.bundles.CustomMessage" var = "lang"/>
<fmt:message key="verb.go" bundle="${lang}"/>

4.11. The <fmt:requestEncoding> Tag

The <fmt:requestEncoding> tag is useful in specifying the encoding type for forms with an action type of post.

The name of the character encoding to use is supplied through the key attribute of the <fmt:requestEncoding> tag.

Let’s see an example below:

<fmt:requestEncoding value = "UTF-8" />

5. XML Tags

JSTL XML tag library provides convenient ways for interacting with XML data within a JSP.

To be able to access these XML tags, we’d add the tag library to our JSP by:

<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

Let’s look at the different tags in the JSTL XML tags library.

5.1. The <x:out> Tag

The <x:out> tag is similar to <%= %> scriptlet tag in JSP but <x:out> is specifically used for XPath expressions.

<x:out> tag has a select and escapeXML attributes used for specifying the XPath expression to evaluate a String and to enable escaping of special XML characters respectively.

A simple example is:

<x:out select="$output/items/item[1]/name"/>

$output in the above refers to a preloaded XSL file.

5.2. The <x:parse> Tag

The <x:parse> tag is used for parsing the XML data specified in its xml or doc attribute or enclosure. A typical example would be:

<x:parse xml="${xmltext}" var="output"/>

5.3. The <x:set> Tag

The <x:set> tag sets the variable specified in its var attribute to the evaluated XPath expression passed to its select attribute. A typical example would be:

<x:set var="fragment" select="$output//item"/>

5.4. The <x:if> Tag

The <x:if> tag processes its body if the XPath expression supplied to its select attribute evaluates to true.

The result of the evaluation can be stored in its var attribute.

A simple use case will look like:

<x:if select="$output//item">
    Document has at least one <item> element.
</x:if>

5.5. The <x:forEach> Tag

The <x:forEach> tag is used for looping over nodes in an XML document. The XML document is supplied through <x:forEach> tag’s select attribute.

Just like the <c:forEach> core tag, <x:forEach> tag has begin, end and step attributes.

Thus, we’d have:

<ul class="items">
    <x:forEach select="$output/items/item/name" var="item">
        <li>Item Name: <x:out select="$item"/></li>
    </x:forEach>
</ul>

5.6. <x:choose>, <x:when> and <x:otherwise> Tags

The <x:choose> tag is a parent tag that is used in performing switch-like or if/else-if/else expressions and has no attributes but encloses <x:when> and <x:otherwise> tags.

<x:when> tag is similar if/else-if and takes a select attribute which holds the expression to be evaluated.

<x:otherwise> tag is similar to else/default clause and has no attribute.

Below, we show a sample use case:

<x:choose>
    <x:when select="$output//item/category = 'Sneakers'">
        Item category is Sneakers
    </x:when>
    <x:when select="$output//item/category = 'Heels'">
        Item category is Heels
    </x:when>
    <x:otherwise>
       Unknown category.
    </x:otherwise>
</x:choose>

5.7. <x:transform> and <x:param> Tags

The <x:transform> tag transforms an XML document within JSP by applying an eXtensible Stylesheet Language (XSL) to it.

The XML document or String to be transformed is supplied to the doc attribute while the XSL to be applied is passed to the xslt attribute of the <x:transform> tag.

<x:param> tag is a subtag of <x:transform> tag and it is used to set a parameter in the transformation stylesheet.

A simple use case will be of the form:

<c:import url="/items_xml" var="xslt"/>
<x:transform xml="${xmltext}" xslt="${xslt}">
    <x:param name="bgColor" value="blue"/>
</x:transform>

6. SQL Tags

JSTL SQL tag library provides tags for performing relational database operations.

To enable JSTL SQL tags, we add the taglib to our JSP:

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>

JSTL SQL tags support different databases including MySQL, Oracle and Microsoft SQL Server.

Next, we’ll look at the different SQL tags available.

6.1. The <sql:setDataSource> Tag

The <sql:setDataSource> tag is used for defining the JDBC configuration variables.

These configuration variables are held in the driver, url, user, password and dataSource attributes of the <sql:setDataSource> tag as shown below:

<sql:setDataSource var="dataSource" driver="com.mysql.cj.jdbc.Driver"
  url="jdbc:mysql://localhost/test" user="root" password=""/>

In the above, the var attribute holds a value that identifies the associated database.

6.2. The <sql:query> Tag

The <sql:query> tag is used to execute an SQL SELECT statement with the result stored in a scoped variable defined in its var attribute. Typically, we’d define this as:

<sql:query dataSource="${dataSource}" var="result">
    SELECT * from USERS;
</sql:query>

<sql:query> tag’s sql attribute holds the SQL command to be executed. Other attributes include maxRows, startRow, and dataSource.

6.3. The <sql:update> Tag

The <sql:update> tag is similar to <sql:query> tag but executes only SQL INSERT, UPDATE or DELETE operations which do not require a return value.

An example usage would be:

<sql:update dataSource="${dataSource}" var="count">
    INSERT INTO USERS(first_name, last_name, email) VALUES
      ('Grace', 'Adams', '[email protected]');
</sql:update>

<sql:update> tag’s var attribute holds the number of rows that were affected by the SQL statement specified in its sql attribute.

6.4. The <sql:param> Tag

The <sql:param> tag is a sub tag that can be used within <sql:query> or <sql:update> tag to supply a value for a value placeholder in the sql statement as this:

<sql:update dataSource = "${dataSource}" var = "count">
    DELETE FROM USERS WHERE email = ?
    <sql:param value = "[email protected]" />
</sql:update>

<sql:param> tag has a single attribute; value which holds the value to be supplied.

6.5. The <sql:dateParam> Tag

The <sql:dateParam> tag is used within <sql:query> or <sql:update> tag to supply a date and time value for a value placeholder in the sql statement.

We can define this in our JSP like this:

<sql:update dataSource = "${dataSource}" var = "count">
    UPDATE Users SET registered = ? WHERE email = ?
    <sql:dateParam value = "<%=registered%>" type = "DATE" />
    <sql:param value = "<%=email%>" />
</sql:update>

Like the <sql:param> tag, <sql:dateParam> tag has a value attribute with an additional type attribute whose value can be one of date, time or timestamp (date and time).

6.6. The <sql:transaction> Tag

The <sql:transaction> tag is used to create JDBC transaction-like operation by grouping <sql:query> and <sql:update> tags together like this:

<sql:transaction dataSource = "${dataSource}">
    <sql:update var = "count">
        UPDATE Users SET first_name = 'Patrick-Ellis' WHERE
          email='[email protected]'
    </sql:update>
    <sql:update var = "count">
        UPDATE Users SET last_name = 'Nelson' WHERE 
          email ='[email protected]'
    </sql:update>
    <sql:update var = "count">
        INSERT INTO Users(first_name, last_name, email) 
          VALUES ('Grace', 'Adams', '[email protected]');
    </sql:update>
</sql:transaction>

<sql:transaction> tag ensures that all database operations are processed successfully (committed) or all fail gracefully (rolled back) if an error occurs in any of the operations.

7. JSTL Functions

JSTL methods are utilities for data manipulation within JSP. While some functions take different data types, most of them are dedicated for String manipulation.

To enable JSTL methods in JSP, we’d add the taglib to our page:

<%@ taglib prefix = "fn"
  uri = "http://java.sun.com/jsp/jstl/functions" %>

Let’s look at these functions and how to use them.

7.1. fn:contains() and fn:containsIgnoreCase()

The fn:contains() method evaluates a String to check if it contains a given substring like this:

<c:set var = "string1" value = "This is first string"/>
<c:if test = "${fn:contains(string1, 'first')}">
    <p>Found 'first' in string<p>
</c:if>

The fn:contains() function takes two String arguments; the first is the source String and the second argument is the substring. It returns a boolean depending on the result of the evaluation.

The fn:containsIgnoreCase() function is a case-insensitive variant of the fn:contains() method and can be used like this:

<c:if test = "${fn:containsIgnoreCase(string1, 'first')}">
    <p>Found 'first' string<p>
</c:if>
<c:if test = "${fn:containsIgnoreCase(string1, 'FIRST')}">
    <p>Found 'FIRST' string<p>
</c:if>

7.3. The fn:endsWith() Function

The fn:endsWith() function evaluates a String to check if its suffix matches another substring. It takes two arguments; the first argument is the String whose suffix is to be tested while the second argument is the tested suffix.

We can define this like:

<c:if test = "${fn:endsWith(string1, 'string')}">
    <p>String ends with 'string'<p>
</c:if>

7.4. The fn:escapeXml() Function

The fn:escapeXML() function is used to escape XML markup in the input String like this:

<p>${fn:escapeXml(string1)}</p>

7.5. The fn:indexOf() Function

The fn:indexOf() function looks through a String and returns the index of the first occurrence of a given substring.

It takes two arguments; the first is the source String and the second argument is the substring to match and return the first occurrence.

fn:indexOf() function returns an integer and can be used like:

<p>Index: ${fn:indexOf(string1, "first")}</p>

7.6. The fn:join() Function

The fn:join() function concatenates all elements of an array into a single String and can be used like this:

<c:set var = "string3" value = "${fn:split(string1, ' ')}" />
<c:set var = "string4" value = "${fn:join(string3, '-')}" />

7.7. The fn:length() Function

The fn:length() function returns the number of elements in the given collection or the number of characters in the given String.

The fn:length() function takes a single Object which can either be a collection or a String and returns an integer like this:

<p>Length: ${fn:length(string1)}</p>

7.8. The fn:replace() Function

The fn:replace() function replaces all occurrences of a substring in a String with another String.

It takes three arguments; the source String, the substring to lookup in the source and the String to replace all occurrences of the substring just like this:

<c:set var = "string3" value = "${fn:replace(string1, 'first', 'third')}" />

7.9. The fn:split() Function

The fn:split() function performs split operation on a String using the specified delimiter. Here is an example usage:

<c:set var = "string3" value = "${fn:split(string1, ' ')}" />

7.10. The fn:startsWith() Function

The fn:startsWith() function checks the prefix of a String and returns true if it matches a given substring like this:

<c:if test = "${fn:startsWith(string1, 'This')}">
    <p>String starts with 'This'</p>
</c:if>

7.11. The fn:substring() Function

The fn:substring() function creates a substring from a source String at the starting and ending indices specified. We’d use it like this:

<c:set var = "string3" value = "${fn:substring(string1, 5, 15)}" />

7.12. The fn:substringAfter() Function

The fn:substringAfter() function checks a source String for a given substring and returns the String immediately after the first occurrence of the specified substring.

We’d use it like this:

<c:set var = "string3" value = "${fn:substringAfter(string1, 'is')}" />

7.13. The fn:substringBefore() Function

The fn:substringBefore() function checks a source String for a given substring and returns the String just before the first occurrence of the specified substring.

In our JSP page, it’ll look like this:

<c:set var = "string3" value = "${fn:substringBefore(string1, 'is')}" />

7.14. The fn:toLowerCase() Function

The fn:to LowerCase() function transforms all characters in a String to lowercase and can be used like this:

<c:set var = "string3" value = "${fn:toLowerCase(string1)}" />

7.15. The fn:toUpperCase() Function

The fn:toUpperCase() function transforms all characters in a String to uppercase:

<c:set var = "string3" value = "${fn:toUpperCase(string1)}" />

7.16. The fn:trim() Function

The fn:trim() function removes preceding and trailing whitespaces in a String:

<c:set var = "string1" value = "This is first String    "/>

9. Conclusion

In this extensive article, we’ve looked at the various JSTL tags and how to use them.

As usual, code snippets can be found over on GitHub.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS