Using JSTL

JSTL tags can be used to replace much of the Java scriptlets in JSP. JSTL tags are classified in five broad groups:

  • Core: Covers flow control and variable support among other things
  • XML: Tags to process XML documents
  • i18n: Tags to support internationalization
  • SQL: Tags to access database
  • Functions: Tags to perform some of the common string operations


See http://docs.oracle.com/javaee/5/tutorial/doc/bnake.html for more details on JSTL.

We will modify the login JSP to use JSTL, so that there are no Java scriptlets in it:

  1. Download JSTL libraries for APIs and their implementation. At the time of writing, the latest .jar files are javax.servlet.jsp.jstl-api-1.2.1.jar (http://search.maven.org/remotecontent?filepath=javax/servlet/jsp/jstl/javax.servlet.jsp.jstl-api/1.2.1/javax.servlet.jsp.jstl-api-1.2.1.jar) and javax.servlet.jsp.jstl-1.2.1.jar (http://search.maven.org/remotecontent?filepath=org/glassfish/web/javax.servlet.jsp.jstl/1.2.1/javax.servlet.jsp.jstl-1.2.1.jar). Make sure that these files are copied to WEB-INF/lib. All .jar files in this folder are added to the classpath of the web application.

  2. We need to add a declaration for JSTL in our JSP. Add the following taglib declaration below the first page declaration (<%@ page language="java" ...>):
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

The taglib declaration contains the URL of the tag library and prefix. All tags in the tag library are accessed using prefix in JSP.

  1. Replace <%String errMsg = null; %> with the set tag of JSTL:
<c:set var="errMsg" value="${null}"/> 
<c:set var="displayForm" value="${true}"/> 

We have enclosed the value in ${}. This is called Expression Language (EL). You enclose the Java expression in JSTL in ${}.

  1. Replace the following code:
<%if ("POST".equalsIgnoreCase(request.getMethod()) && 
request.getParameter("submit") != null) {%> 

With the if tag of JSTL:

<c:if test="${"POST".equalsIgnoreCase(pageContext.request 
.method) && pageContext.request.getParameter("submit") != 
null}">

The request object is accessed in the JSTL tag via pageContext.

  1. JavaBean tags go within the if tag. There is no change in this code:
<jsp:useBean id="loginBean" 
  class="packt.book.jee_eclipse.ch2.bean.LoginBean"> 
  <jsp:setProperty name="loginBean" property="*"/> 
</jsp:useBean> 
  1.  We then add tags to call loginBean.isValidUser() and based on its return value, to set messages. However, we can't use the if tag of JSTL here, because we need to write the else statement too. JSTL does not have a tag for else. Instead, for multiple if...else statements, you need to use the choose statement, which is somewhat similar to the switch statement:
<c:choose> 
  <c:when test="${!loginBean.isValidUser()}"> 
    <c:set var="errMsg" value="Invalid user id or password. Please 
try again"/> </c:when> <c:otherwise> <h2><c:out value="Welcome admin !"/></h2> <c:out value="You are successfully logged in"/> <c:set var="displayForm" value="${false}"/> </c:otherwise> </c:choose>

If the user credentials are not valid, we set the error message. Or (in the c:otherwise tag), we print the welcome message and set the displayForm flag to false. We don't want to display the login form if the user is successfully logged in.

  1. We will now replace another if scriptlet code by <%if%> tag. Replace the following code snippet:
<%if (errMsg != null) { %> 
  <span style="color: red;"><%out.print(errMsg); %></span> 
<%} %> 

With the following code:

<c:if test="${errMsg != null}"> 
  <span style="color: red;"> 
    <c:out value="${errMsg}"></c:out> 
  </span> 
</c:if>

Note that we have used the out tag to print an error message.

  1.  Finally, we enclose the entire <body> content in another JSTL if tag:
<c:if test="${displayForm}"> 
<body> 
   ... 
</body> 
</c:if> 

Here is the complete source code of the JSP:

<%@ page language="java" contentType="text/html; charset=UTF-8" 
    pageEncoding="UTF-8"%> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF- 
8"> <title>Login</title> </head> <c:set var="errMsg" value="${null}"/> <c:set var="displayForm" value="${true}"/> <c:if test="${"POST".equalsIgnoreCase(pageContext.request.method) && pageContext.request.getParameter("submit") != null}"> <jsp:useBean id="loginBean"
class="packt.book.jee_eclipse.ch2.bean.LoginBean"> <jsp:setProperty name="loginBean" property="*"/> </jsp:useBean> <c:choose> <c:when test="${!loginBean.isValidUser()}"> <c:set var="errMsg" value="Invalid user id or password.
Please try again"/> </c:when> <c:otherwise> <h2><c:out value="Welcome admin !"/></h2> <c:out value="You are successfully logged in"/> <c:set var="displayForm" value="${false}"/> </c:otherwise> </c:choose> </c:if> <c:if test="${displayForm}"> <body> <h2>Login:</h2> <!-- Check error message. If it is set, then display it --> <c:if test="${errMsg != null}"> <span style="color: red;"> <c:out value="${errMsg}"></c:out> </span> </c:if> <form method="post"> User Name: <input type="text" name="userName"><br> Password: <input type="password" name="password"><br> <button type="submit" name="submit">Submit</button> <button type="reset">Reset</button> </form> </body> </c:if> </html>

As you can see, there are no Java scriptlets in the preceding code. All of them, from the previous code, are replaced by tags. This makes it easy for web designers to edit the page without worrying about Java scriptlets.

One last note before we leave the topic of JSP. In real-world applications, you would probably forward the request to another page after the user successfully logs in, instead of just displaying a welcome message on the same page. You could use the <jsp:forward> tag to achieve this.