11.7. Looping Without Generating BodyContent

In JSP 1.1, the only way to make an iterative tag is to return EVAL_BODY_TAG from the doAfterBody method, thus instructing the system to reevaluate the tag body. If the doStartTag returns EVAL_BODY_TAG, the system copies the tag body into a BodyContent object and invokes doAfterBody. The BodyTagSupport class overrides doStartTag to automatically return EVAL_BODY_TAG, so you only need to write doAfterBody when using BodyTagSupport. The problem with this approach is that doAfterBody must manually generate the tag body’s output by extracting it from the BodyContent object in which the system wraps the body. This is fine if you actually want to manipulate the body. But, if you merely want to iterate, you must use the somewhat clumsy BodyContent object and the system must repeatedly copy the tag body.

JSP 1.2 provides a solution that is both simpler and more efficient. If a tag implements IterationTag, doStartTag can return EVAL_BODY_INCLUDE to instruct the system to output the tag body without first copying it. Then, if the doAfterBody method returns EVAL_BODY_AGAIN, the process is repeated. Since the TagSupport class now implements IterationTag, simple iterative tags in JSP 1.2 need not use BodyTagSupport at all.

The following two subsections present simple examples that contrast the JSP 1.1 and JSP 1.2 approaches.

JSP 1.1 Loop Tag

Listing 11.31 shows a simple iterative tag that uses the JSP 1.1 approach. It extends the BodyTagSupport class, overrides doAfterBody, extracts the tag body from the BodyContent object, and outputs it to the client. The doAfterBody method returns EVAL_BODY_TAG to indicate that looping should continue; it returns SKIP_BODY when done.

Listing 11.32 shows a TLD file that declares the tag; Listing 11.33 shows a JSP page that uses the tag, supplying a request-time form parameter (repeats) to dictate how many repetitions should be executed. Figure 11-11 shows the result.

Figure 11-11. Result of repeat-test1.jsp when the user supplies a repeats parameter of 25.


Listing 11.31. RepeatTag1.java
package moreservlets.tags; 

import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 
import java.io.*; 

/** A tag that repeats the body the specified 
 *  number of times. JSP 1.1 version. 
 */ 

public class RepeatTag1 extends BodyTagSupport {
  private int reps; 

  public void setReps(String repeats) {
    try {
      reps = Integer.parseInt(repeats); 
    } catch(NumberFormatException nfe) {
      reps = 1; 
    } 
  } 

  public int doAfterBody() {
    if (reps-- >= 1) {
      BodyContent body = getBodyContent(); 
      try {
        JspWriter out = body.getEnclosingWriter();
							out.println(body.getString());
							body.clearBody(); // Clear for next evaluation 
      } catch(IOException ioe) {
        System.out.println("Error in RepeatTag1: " + ioe); 
      } 
      return(EVAL_BODY_TAG); 
    } else {
      return(SKIP_BODY); 
    } 
  } 
} 

Listing 11.32. repeat-taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE taglib 
 PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" 
 "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 

<taglib> 
  <tlib-version>1.0</tlib-version> 
  <jsp-version>1.2</jsp-version> 
  <short-name>repeat-tags</short-name> 
  <description> 
    A tag library that has two tags: repeatTag1 and repeatTag2. 
    These are JSP 1.1 and JSP 1.2 versions of simple 
    looping tags. 
  </description> 

  <!-- An iterative tag. JSP 1.1 version. --> 
  <tag>
							<name>repeat1</name>
							<tag-class>moreservlets.tags.RepeatTag1</tag-class>
							<body-content>JSP</body-content>
							<description>
							Repeats body the specified number of times.
							</description>
							<attribute>
							<name>reps</name>
							<required>true</required>
							<!-- rtexprvalue indicates whether attribute
							can be a JSP expression. -->
							<rtexprvalue>true</rtexprvalue>
							</attribute>
							</tag> 

  <!-- An iterative tag. JSP 1.2 version. --> 
  <tag> 
    <name>repeat2</name> 
    <tag-class>moreservlets.tags.RepeatTag2</tag-class> 
    <body-content>JSP</body-content> 
    <description> 
      Repeats body the specified number of times. 
    </description> 
    <attribute> 
      <name>reps</name> 
      <required>true</required> 
      <!-- rtexprvalue indicates whether attribute 
           can be a JSP expression. --> 
      <rtexprvalue>true</rtexprvalue> 
    </attribute> 
  </tag> 
</taglib> 

Listing 11.33. repeat-test1.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
<TITLE>Some Random Numbers</TITLE> 
<LINK REL=STYLESHEET 
      HREF="styles.css" 
      TYPE="text/css"> 
</HEAD> 

<BODY> 
<TABLE BORDER=5 ALIGN="CENTER"> 
  <TR><TH CLASS="TITLE"> 
      Some Random Numbers 
</TABLE> 
<P> 
<%@ taglib uri="/WEB-INF/repeat-taglib.tld" prefix="msajsp" %> 
<UL> 
<msajsp:repeat1 reps='<%= request.getParameter("repeats") %>'> 
  <LI><%= Math.random() %> 
</msajsp:repeat1> 
</UL> 
</BODY> 
</HTML> 

JSP 1.2 Loop Tag

Listing 11.34 shows a simple iterative tag that uses the JSP 1.2 approach. It extends the TagSupport class, overrides doStartTag to return EVAL_BODY_INCLUDE, and overrides doAfterBody to either return EVAL_BODY_AGAIN (keep looping) or SKIP_BODY (done). No BodyContent: no need for the programmer to extract it, and no need for the system to waste time and memory copying the tag body into it.

Listing 11.35 shows a JSP page that uses the tag, supplying a request-time form parameter (repeats) to dictate how many repetitions should be executed. Figure 11-12 shows the result.

Figure 11-12. Result of repeat-test2.jsp when the user supplies a repeats parameter of 25.


Listing 11.34. RepeatTag2.java
package moreservlets.tags; 

import javax.servlet.jsp.*; 
import javax.servlet.jsp.tagext.*; 
import java.io.*; 

/** A tag that repeats the body the specified 
 *  number of times. JSP 1.2 version. 
 */ 

public class RepeatTag2 extends TagSupport {
  private int reps; 
  public void setReps(String repeats) {
    try {
      reps = Integer.parseInt(repeats); 
    } catch(NumberFormatException nfe) {
      reps = 1; 
    } 
  } 

  public int doStartTag() {
    if (reps >= 1) {
      return(EVAL_BODY_INCLUDE); 
    } else {
      return(SKIP_BODY); 
    } 
  } 

  public int doAfterBody() {
    if (reps-- > 1) {
      return(EVAL_BODY_AGAIN); 
    } else {
      return(SKIP_BODY); 
    } 
  } 
} 

Listing 11.35. repeat-test2.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<HTML> 
<HEAD> 
<TITLE>Some Random Numbers</TITLE> 
<LINK REL=STYLESHEET 
      HREF="styles.css" 
      TYPE="text/css"> 
</HEAD> 

<BODY> 
<TABLE BORDER=5 ALIGN="CENTER"> 
  <TR><TH CLASS="TITLE"> 
      Some Random Numbers 
</TABLE> 
<P> 
<%@ taglib uri="/WEB-INF/repeat-taglib.tld" prefix="msajsp" %> 
<UL> 
<msajsp:repeat2 reps='<%= request.getParameter("repeats") %>'> 
  <LI><%= Math.random() %> 
</msajsp:repeat2> 
</UL> 
</BODY> 
</HTML> 

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.147.193