Java EE Tutorials - JSP and the JSTL

In our last post, we talked about how to write custom JSP tags and add them to a taglib. Today we will go over the most famous taglib of all. The JSTL, or Java Standard Tag Library, is exactly what its name says it is. And like the rest of the Java EE family, it is defined by a specification, and implemented by a servlet container. The library tries to define tags which perform the most common tasks you might use on a JSP page, so that you don’t have to write them yourself.

The example code for this post can be found in the jsp_jstl branch of our example repository on Github, and a ZIP file of the code can be found here.

Breakdown of the JSTL

The library is broken up into different categories of tags:

  • Core - contains “core” functions.

  • XML - contains tags for dealing with XML.

  • Internationalization - self explanatory

  • SQL - for interacting with a database. (ummmm …. okay)

  • Functions - mostly contains functions for manipulating strings

Each of these categories is stored in its own namespace, meaning we have to import each one individually into our JSP page if we wish to use them.

The JSP Expression Language

Honestly, I could probably do a whole other post on the JSP Expression Language, but for now a quick intro should do. The JSP EL is a feature introduced in JSP 2.0. It allows us to write JSP Expressions in a simpler form. Instead of using <%= %>, we enclose the expression like so - ${ expression }. I bring this up because the Expression Language is very important in order to make JSTL tags work effectively.

How to use the JSTL

As before, we will need to include a build dependency, one which contains the JSTL API. Here’s the gradle definition:

runtime 'javax.servlet:jstl:1.2'

By defining the runtime scope, we’re telling gradle that we need this dependency at runtime, but not at compile time.

Once we have this defined, we can start using JSTL tags. To do so, we simple include it in a JSP page, just like we’ve done before. For our first example, we’ll start with a simple, but useful feature - the loop tag. Here is a first stab at jstlcoretags.jsp:


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

<c:forEach var="number" begin="5" end="10">
  <c:out value="${number}"></c:out>
<c:forEach>

Note that we used the letter c as the prefix for the JSTL tags. This is not mandatory, but is rather a best practice, to indicate that the tag is from the Core category.

As for the code itself, the c:forEach tag acts as a loop. It defines a start point and an endpoint, as well as a variable which will increment as the loop iterates. Inside the loop, we see the c:out tag. This is used to output content to the page. Notice that it uses an Expression Language statement to output the value of the number variable. If we were to look at this JSP page in the browser, the output would be “5 6 7 8 9 10”.

Now, here’s where things get a bit confusing. The above example is only one way to use the forEach tag. We can also use it to iterate through a Java Collection. Let’s update our JSP page to demonstrate how this is done:


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

<!-- A basic loop -->
<c:forEach var="number" begin="5" end="10">
    <c:out value="${number}"></c:out>
</c:forEach>

<!-- We'll use a scriptlet to create a list to iterate over -->
<%
   // Create an ArrayList with test data
   ArrayList list = new ArrayList();
   list.add("String 1");
   list.add("String 2");
   list.add("String 3");
   pageContext.setAttribute("list", list);
%>


<c:forEach items="${list}" var="item">
    <li><c:out value="${item.toUpperCase()}" />
</c:forEach>

We use a Scriptlet to create an ArrayList object, and then stuff it into the Servlet Context for the page. By placing it in the context, we can refer to it in Expression Language statements.

Now take a look at the forEach block at the bottom of the page. The items attribute specifies the collection to iterate over, and the var attribute is used to specify the current item we’re iterating over. In regular Java code, this would translate to for(String item : list) {.

We then use another c:out tag to output the list item in upper case. This is what the page looks like in the browser:

Let’s enhance this example ever so slightly. I mentioned that there’s a category of JSTL tags containing String functions. Let’s use it to perform the conversion to upper case. Our example now looks like this:


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ page import="java.util.*" %>

<!-- A basic loop -->
<c:forEach var="number" begin="5" end="10">
    <c:out value="${number}"></c:out>
</c:forEach>

<!-- We'll use a scriptlet to create a list to iterate over -->
<%
   // Create an ArrayList with test data
   ArrayList list = new ArrayList();
   list.add("String 1");
   list.add("String 2");
   list.add("String 3");
   pageContext.setAttribute("list", list);
%>


<c:forEach items="${list}" var="item">
    <li><c:out value="${fn:toUpperCase(item)}" /></li>
</c:forEach>

Note that we imported the function tags under the namespace fn, and we used fn:toUpperCase() in the Expression Language statement. The output of this page will be identical.

General Comments

There are many more JSTL tags than what we’ve covered in this post, but going through each of them would be exhausting for both of us. If you’re still curious, I’ll leave you with this link which lists them all.

There’s another reason why I haven’t covered the rest; I’m not entirely sold on the JSTL as a whole. Sure, the forEach tag is much cleaner than slapping a Java for-loop into your page. But the String functions, for example, are no simpler than using the regular methods of the String class, especially when using the Expression Language.

Then you have the SQL tags, which are a whole other story. It was only one post ago that we talked about how it was a bad idea to mix business logic in the presentation layer. But this is exactly what the SQL tags are encouraging.

Personally, I would stick to using only the Core tags, since they’re the only ones which will help keep your page cleaner. Everything else goes against best practices. Use them if you need to, but be careful.

Conclusion

This post wraps up our tour of JSP technology. I’ll leave you with the same advice I’ve been giving this whole time. Don’t be afraid to use JSP pages, and don’t be afraid to put Java code in them if you need to. Just be smart about it. Use good formatting and indentation. And take a look at more complex MVC frameworks if your application is going to feature a complex, dynamic web UI. They can help make things simpler.

At this point, we’ve covered Servlets and JSPs, arguably the most basic, core technologies of the Java EE stack. There’s nothing that really builds directly on top of these two, except maybe JSF, and I’m not ready to try and wrestle with that one right now. Instead, we’ll dive into something entirely different. I haven’t decided exactly what yet, but it will probably be either JPA or JMS.