ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

JSP 1.2: Great News for the JSP Community, Part 2

by Hans Bergsten, author of JavaServer Pages
11/07/2001

The latest version of the JSP specification, JSP 1.2, was released on September 17, 2001. In part one of this article, I described a number of new features that have been added to the specification. In this article, I focus on the details concerning the custom tag handler API.

Two new interfaces

Custom tag developers now have two new interfaces to play with: IterationTag and TryCatchFinally.

The IterationTag interface is implemented by a tag handler that repeatedly evaluates its element body. It is located between the Tag and the BodyTag interfaces in the inheritance hierarchy: IterationTag extends Tag and BodyTag extends IterationTag. A tag handler that needs full control over error conditions may implement the TryCatchFinally interface.

The following sections describe both interfaces in detail.

IterationTag interface

The IterationTag interface contains only one method:

public int doAfterBody(): Called by the container after it has processed the action element's body.

If you think this method looks familiar, you're right. It used to be part of the BodyTag interface. By moving this method to the new IterationTag interface, iterators that do not need access to the element body can be implemented without the overhead associated with maintaining a BodyContent instance.

The doAfterBody() method can return either EVAL_BODY_AGAIN (to iterate over the body) or SKIP_BODY (to stop the iteration). The EVAL_BODY_AGAIN constant is new, replacing the confusingly-named EVAL_BODY_TAG constant used in JSP 1.1.

Here's an example of a tag handler class that implements the IterationTag interface:

package com.foo;

import java.util.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public class MyLoopTag extends TagSupport {
    private Iterator iterator;
    private String items;
    private String var;

     public void setItems(String items) {
        this.items = items;
    }

    public void setVar(String var) {
        this.var = var;
    }

    public int doStartTag() throws JspTagException {
        Collection coll = (Collection)
    pageContext.findAttribute(items);
 if (coll == null) {
     throw new JspTagException("No collection with name "
        + items + " found");
 }
 iterator = coll.iterator();
 if (iterator.hasNext()) {
     pageContext.setAttribute(var, iterator.next());
     return EVAL_BODY_INCLUDE;
 }
 else {
     return SKIP_BODY;
 }
    }

     public int doAfterBody() {
        if (iterator.hasNext()) {
     pageContext.setAttribute(var, iterator.next());
     return EVAL_BODY_AGAIN;
 }
 else {
     return SKIP_BODY;
 }
    }
}

MyLoopTag extends TagSupport. The TagSupport class in JSP 1.2 implements the IterationTag interface instead of the Tag interface and provides default implementations for the methods in both interfaces. To implement an iteration tag, you must override the doStartTag() and the doAfterBody() methods.

Related Reading

JavaServer PagesJavaServer Pages
By Hans Bergsten
Table of Contents
Index
Sample Chapter
Full Description
Read Online -- Safari

In MyLoopTag, the doStartTag() method first retrieves the Collection specified by the items attribute and creates an Iterator for it. If the Iterator contains at least one element, the method makes the first element in the Collection available as a page scope object, with the name specified by the var attribute and returns EVAL_BODY_INCLUDE. This tells the container to add the contents of the loop element's body to the response and call doAfterBody().

The doAfterBody() does the same as doStartTag(), except that it doesn't initialize the Iterator. As long as the Iterator contains at least one more element, doAfterBody() returns EVAL_BODY_AGAIN. When all elements have been processed, it returns SKIP_BODY to stop the iteration.

You can use the loop tag with a Collection that contains beans with firstName and lastName properties like this:

<%@ taglib uri="/demolib" prefix="demo" %>
...
<ul>
  <demo:myLoopTag items="myCollection" var="current">
    <li>
<jsp:getProperty name="current" property="lastName" />,
<jsp:getProperty name="current" property="firstName" />
  </demo:myLoopTag>
</ul>

Pages: 1, 2, 3

Next Pagearrow