|
Tags Working Together
Part:
1
2
(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
|