JSP and JSTL Tutorials - Herong's Tutorial Notes
Dr. Herong Yang, Version 3.09, 2006

Tags Working Together

Part:   1  2 

JSP/JSTL Tutorials - Herong's Tutorial Notes © Dr. Herong Yang

Using Cookies

Using JavaBean Classes

HTTP Response Header Lines

Non ASCII Characters

JSTL and Expression Language

File Upload

Execution Context

JSP Elements

JSP Standard Tag Libraries (JSTL)

JSP Custom Tag

... Table of Contents

(Continued from previous part...)

I am sure you can read this page, and understand what I am doing with the loop. Warning, my "break" tag is not a truly break statement. If there is any additional body content in the loop tag after the "break" tag, it will not be skipped.

Sharing Data with Other Tags

In the previous example, we looked at how tags can be nested inside each other, and how child tags can access parent tags to modify their behavior. In the next example, we will look at how non-nested tags, brother tags, can communicate to each other.

If a tag wants to share data with a brother tag, it must store the data to a common place where both of them have access. Obviously, that common place is the pageContext object. The JSP tag extension facility offers to every tag object the access to pageContext object by the setPageContext() call in Tag interface. If you use the TagSupport implementation class, pageContext is already made available as an instance variable.

If you read the PageContext class API, you will see that it allows you to store and retrieve objects as named attributes at any time. So if one tag wants to share an object to another tag, it can store that object to pageContext; and the other tag can retrieve it from pageContext.

Another advantage of using pageContext to share objects is that JSTL tags are also using pageContext to store and share objects. So if we use it correctly, we can share objects in custom tags with JSTL tags.

Let's look at a very simple example, SetTimeTag.java. It does nothing but storing the current time in milliseconds into pageContext as an attribute with a given name. Once the data is stored in pageContext, any other tags can come and retrieve it.

/**
 * SetTimeTag.java
 * Copyright (c) 2003 by Dr. Herong Yang. All rights reserved.
 */
package herong;
import javax.servlet.jsp.tagext.*;
public class SetTimeTag extends TagSupport {
   private String var = null;
   public void setVar(String v) {
      this.var = v;
   }
   public int doStartTag() {
      Long now = new Long(System.currentTimeMillis());
      pageContext.setAttribute(var,now);
      return SKIP_BODY;
   }
}

The TLD file:

<?xml version="1.0"?>
<!DOCTYPE taglib PUBLIC 
 "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" 
 "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_2.dtd"> 
<!-- HyTaglib.tld
     Copyright (c) 2003 by Dr. Herong Yang
-->
<taglib>
<tlib-version>1</tlib-version>
<jsp-version>1.2</jsp-version> 
<short-name>Herong's Tag Library</short-name> 
<tag>
 <name>setTime</name>
 <tag-class>herong.SetTimeTag</tag-class>
 <body-content>empty</body-content>
 <attribute>
  <name>var</name>
  <required>true</required>
 </attribute>
</tag>
<!-- other tags -->
</taglib>

Here is the testing page:

<?xml version="1.0"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" 
   xmlns:c="http://java.sun.com/jstl/core"
   xmlns:hy="urn:jsptld:/WEB-INF/tlds/HyTaglib.tld" version="1.2"> 
<!-- SetTimeTagTest.jsp
     Copyright (c) 2003 by Dr. Herong Yang
-->
<jsp:directive.page contentType="text/html"/>
<html><body>
<hy:setTime var="t1"/>
<p>Checking prime numbers:</p>
<c:set var="upperLimit" value="${50}"/>
<c:forEach var="i" begin="${3}" end="${upperLimit}">
 <c:set var="isPrime" value="${true}"/>
 <c:forEach var="j" begin="${2}" end="${i-1}">
  <c:if test="${i%j == 0}">
   <c:set var="isPrime" value="${false}"/>
   <!-- We should break the loop here -->
  </c:if>
 </c:forEach>
 <c:choose>
  <c:when test="${isPrime}">
   <c:out value="${i} is a prime number."/><br/>
  </c:when>
  <c:otherwise>
   <c:out value="${i} is a not prime number."/><br/>
  </c:otherwise>
 </c:choose>
</c:forEach>
<hy:setTime var="t2"/>
<p><c:out value="Total time = ${t2-t1} milliseconds."/></p>
</body></html>
</jsp:root>

The output:

Checking prime numbers:

3 is a prime number.
4 is a not prime number.
5 is a prime number.
6 is a not prime number.
7 is a prime number.
8 is a not prime number.
9 is a not prime number.
10 is a not prime number.
...
50 is a not prime number.

Total time = 110 milliseconds.

As you can see from the testing page, I used "setTime" to store the current time at the beginning of my prime number checking process as "t1", and the current time at the end as "t2". Then I used "out" to retrieve them and calculate their difference in a single expression.

Part:   1  2 

Dr. Herong Yang, updated in 2006
JSP and JSTL Tutorials - Herong's Tutorial Notes - Tags Working Together