JSTL Formatting & Functions Tags
Learn the JSTL fmt tag library for formatting dates and numbers, plus the fn function library for common string operations in Expression Language.
Introduction
In the previous lesson you used the JSTL core tag library (c:) to handle loops and conditionals without scriptlets. JSTL also ships two more tag libraries you will reach for constantly in real applications: fmt, for locale-aware formatting of dates and numbers, and fn, a set of EL functions for everyday string manipulation. Together they let you present data cleanly without writing a single line of Java inside your JSP markup.
- How to import the fmt and functions tag libraries.
- How to format dates with <fmt:formatDate>.
- How to format numbers and currency with <fmt:formatNumber>.
- How to use fn: functions like length, toUpperCase, and contains.
The fmt Tag Library
Like the core library, fmt must be declared at the top of your JSP page with a taglib directive. The functions library uses a separate URI and prefix, conventionally fn.
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>Both tag libraries ship inside the jstl-1.2.jar (or the Jakarta equivalent jakarta.servlet.jsp.jstl) that you already added to WEB-INF/lib in the previous lesson. No extra dependency is needed to use fmt or fn.
Formatting Dates with <fmt:formatDate>
Java date objects do not print in a human-friendly way by default. The <fmt:formatDate> tag takes a java.util.Date value and a pattern (or a built-in style) and renders it as a string, without you ever touching SimpleDateFormat in a scriptlet.
// In a servlet, before forwarding to the JSPrequest.setAttribute("today", new java.util.Date());<p>Today is: <fmt:formatDate value="${today}" pattern="dd MMMM yyyy" /></p><p>Time now: <fmt:formatDate value="${today}" type="time" pattern="hh:mm a" /></p><p>Full stamp: <fmt:formatDate value="${today}" type="both" dateStyle="long" timeStyle="short" /></p>Click Run to see what this code prints.
- type="date" (default) — renders only the date portion.
- type="time" — renders only the time portion.
- type="both" — renders date and time together.
Formatting Numbers with <fmt:formatNumber>
<fmt:formatNumber> handles currency, percentages, and plain decimal formatting, respecting grouping separators and a configurable number of fraction digits.
<p>Price: <fmt:formatNumber value="1499.5" type="currency" currencySymbol="$" /></p><p>Discount: <fmt:formatNumber value="0.185" type="percent" maxFractionDigits="1" /></p><p>Plain: <fmt:formatNumber value="1234567.891" type="number" maxFractionDigits="2" /></p>Click Run to see what this code prints.
Common <fn:> String Functions
The functions library gives Expression Language a small standard library of string helpers. These are called directly inside ${...} using the fn: prefix, no tag body required.
| Function | Purpose | Example |
|---|---|---|
| fn:length(x) | Length of a string or collection | \${fn:length(username)} |
| fn:toUpperCase(x) | Converts to uppercase | \${fn:toUpperCase(username)} |
| fn:toLowerCase(x) | Converts to lowercase | \${fn:toLowerCase(username)} |
| fn:contains(a,b) | True if a contains b | \${fn:contains(email, "@")} |
| fn:trim(x) | Removes leading/trailing whitespace | \${fn:trim(rawInput)} |
| fn:substring(x,s,e) | Extracts a substring | \${fn:substring(username, 0, 3)} |
| fn:replace(x,a,b) | Replaces occurrences of a with b | \${fn:replace(phone, "-", "")} |
<p>Username length: ${fn:length(username)}</p><p>Shout: ${fn:toUpperCase(username)}</p><p>Has @ symbol: ${fn:contains(email, "@")}</p><p>First 3 letters: ${fn:substring(username, 0, 3)}</p>Click Run to see what this code prints.
Common Mistakes
- Forgetting to declare the fn taglib and getting an "Unable to resolve tag" style error.
- Passing a java.lang.String date into <fmt:formatDate> instead of a real java.util.Date object — it will throw a ClassCastException at runtime.
- Assuming <fmt:formatNumber> automatically rounds — always set maxFractionDigits explicitly for money.
- Confusing fn:length on a null value, which throws instead of returning 0; guard with an empty-check first.
Best Practices
- Always format currency with type="currency" rather than manually concatenating a $ sign.
- Keep date pattern strings consistent across a page for a uniform look.
- Prefer fn: functions over scriptlet String methods — they keep JSP markup declarative.
- Set a default locale with <fmt:setLocale> near the top of the page if you support multiple regions.
Frequently Asked Questions
Yes. Both extend java.util.Date, so they work directly with the value attribute.
Yes, unless you override it with <fmt:setLocale>, in which case grouping and decimal symbols follow that locale.
Functionally yes — it removes leading and trailing whitespace and returns a new string.
Key Takeaways
- The fmt library formats dates and numbers without scriptlets.
- <fmt:formatDate> needs a real Date object and a pattern or style.
- <fmt:formatNumber> supports currency, percent, and plain number types.
- The fn library provides EL-native string helpers like length, contains, and substring.
Summary
With fmt and fn in your toolkit, you can present dates, currency, and text cleanly using pure Expression Language — no Java formatting classes required inside the view. Next, you will look at the other direction of the data flow: how JSP pages receive input from the user through HTML forms.