PrimeTag.java Custom tag that outputs a random prime number of a user-specifiable approximate length
package cwp.tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
/** Generates an N-digit random prime (default N = 50).
* Extends SimplePrimeTag, adding a length attribute
* to set the size of the prime. The doStartTag
* method of the parent class uses the len field
* to determine the approximate length of the prime.
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class PrimeTag extends SimplePrimeTag {
public void setLength(String length) {
try {
len = Integer.parseInt(length);
} catch(NumberFormatException nfe) {
len = 50;
}
}
}
Aug 28
PrimeTag.java Custom tag that outputs a random prime number of a user-specifiable approximate length
Aug 28
SimplePrimeTag.java Custom tag that outputs a random prime number of a fixed approximate length
SimplePrimeTag.java Custom tag that outputs a random prime number of a fixed approximate length
package cwp.tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import java.math.*;
import cwp.*;
/** Generates a prime of approximately 50 digits.
* (50 is actually the length of the random number
* generated -- the first prime above that number will
* be returned.)
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class SimplePrimeTag extends TagSupport {
protected int len = 50;
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
BigInteger prime = Primes.nextPrime(Primes.random(len));
out.print(prime);
} catch(IOException ioe) {
System.out.println("Error generating prime: " + ioe);
}
return(SKIP_BODY);
}
}
Aug 28
cwp-taglib.tld Tag Library Descriptor file used by the custom tags in this chapter.
cwp-taglib.tld Tag Library Descriptor file used by the custom tags in this chapter. <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <!-- a tag library descriptor --> <taglib> <!-- after this the default space is "http://java.sun.com/j2ee/dtds/jsptaglibrary_1_2.dtd" --> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>cwp</shortname> <!-- ** CHANGED FROM "urn" TO "uri" IN TOMCAT 3.1 final ** --> <uri></uri> <info> A tag library from Core Web Programming Java 2 Edition, . </info> <!-- <tag> The name (after prefix) tag will have in JSP code <name>example</name> The actual class implementing tag. In Tomcat 3.1, it MUST be in a package. <tagclass>cwp.tags.ExampleTag</tagclass> Descriptive information about tag. <info>Simplest example: inserts one line of output</info> One of three values describing what goes between start and end tag. empty: no body JSP: body that is evaluated by container normally, then possibly processed by tag tagdependent: body is only processed by tag; JSP in body is not evaluated. ** NOTE: TOMCAT 3.1 FINAL DOES NOT SUPPORT BODYCONTENT ** ** THE BETA SUPPORTED IT, AND IT IS PART OF SPEC, BUT... ** <bodycontent>empty</bodycontent> </tag> --> <tag> <name>example</name> <tagclass>cwp.tags.ExampleTag</tagclass> <info>Simplest example: inserts one line of output</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>empty</bodycontent> --> </tag> <tag> <name>simplePrime</name> <tagclass>cwp.tags.SimplePrimeTag</tagclass> <info>Outputs a random 50-digit prime.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>empty</bodycontent> --> </tag> <tag> <name>prime</name> <tagclass>cwp.tags.PrimeTag</tagclass> <info>Outputs a random N-digit prime.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>empty</bodycontent> --> <attribute> <name>length</name> <required>false</required> </attribute> </tag> <tag> <name>heading</name> <tagclass>cwp.tags.HeadingTag</tagclass> <info>Outputs a 1-cell table used as a heading.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> <attribute> <name>bgColor</name> <required>true</required> <!-- bgColor is required --> </attribute> <attribute> <name>color</name> <required>false</required> </attribute> <attribute> <name>align</name> <required>false</required> </attribute> <attribute> <name>fontSize</name> <required>false</required> </attribute> <attribute> <name>fontList</name> <required>false</required> </attribute> <attribute> <name>border</name> <required>false</required> </attribute> <attribute> <name>width</name> <required>false</required> </attribute> </tag> <tag> <name>debug</name> <tagclass>cwp.tags.DebugTag</tagclass> <info>Includes body only if debug param is set.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> </tag> <tag> <name>filter</name> <tagclass>cwp.tags.FilterTag</tagclass> <info>Replaces HTML-specific characters in body.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> </tag> <tag> <name>repeat</name> <tagclass>cwp.tags.RepeatTag</tagclass> <info>Repeats body the specified number of times.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> <attribute> <name>reps</name> <required>true</required> <!-- rtexprvalue indicates whether attribute can be a JSP expression. --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>if</name> <tagclass>cwp.tags.IfTag</tagclass> <info>if/condition/then/else tag.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> </tag> <tag> <name>condition</name> <tagclass>cwp.tags.IfConditionTag</tagclass> <info>condition part of if/condition/then/else tag.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> </tag> <tag> <name>then</name> <tagclass>cwp.tags.IfThenTag</tagclass> <info>then part of if/condition/then/else tag.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> </tag> <tag> <name>else</name> <tagclass>cwp.tags.IfElseTag</tagclass> <info>else part of if/condition/then/else tag.</info> <!-- TOMCAT 3.1 DOES NOT SUPPORT BODYCONTENT <bodycontent>JSP</bodycontent> --> </tag> </taglib>
Aug 28
SharedCounts1.jsp, SharedCounts2.jsp, and SharedCounts3.jsp Three pages that all use the AccessCountBean. Results you get depend on which page is hit first and how many total hits the combined pages receive.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-- Example of sharing beans. Taken from Core Web Programming Java 2 Edition from Prentice Hall and Sun Microsystems Press, . May be freely used or adapted. --> <HTML> <HEAD> <TITLE>Shared Access Counts: Page 1</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> Shared Access Counts: Page 1</TABLE> <P> <jsp:useBean id="counter" class="cwp.AccessCountBean" scope="application"> <jsp:setProperty name="counter" property="firstPage" value="SharedCounts1.jsp" /> </jsp:useBean> Of SharedCounts1.jsp (this page), <A HREF="SharedCounts2.jsp">SharedCounts2.jsp</A>, and <A HREF="SharedCounts3.jsp">SharedCounts3.jsp</A>, <jsp:getProperty name="counter" property="firstPage" /> was the first page accessed. <P> Collectively, the three pages have been accessed <jsp:getProperty name="counter" property="accessCount" /> times. </BODY> </HTML> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-- Example of sharing beans. Taken from Core Web Programming Java 2 Edition from Prentice Hall and Sun Microsystems Press, . May be freely used or adapted. --> <HTML> <HEAD> <TITLE>Shared Access Counts: Page 2</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> Shared Access Counts: Page 2</TABLE> <P> <jsp:useBean id="counter" class="cwp.AccessCountBean" scope="application"> <jsp:setProperty name="counter" property="firstPage" value="SharedCounts2.jsp" /> </jsp:useBean> Of SharedCounts2.jsp (this page), <A HREF="SharedCounts1.jsp">SharedCounts1.jsp</A>, and <A HREF="SharedCounts3.jsp">SharedCounts3.jsp</A>, <jsp:getProperty name="counter" property="firstPage" /> was the first page accessed. <P> Collectively, the three pages have been accessed <jsp:getProperty name="counter" property="accessCount" /> times. </BODY> </HTML> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!-- Example of sharing beans. Taken from Core Web Programming Java 2 Edition from Prentice Hall and Sun Microsystems Press, . May be freely used or adapted. --> <HTML> <HEAD> <TITLE>Shared Access Counts: Page 3</TITLE> <LINK REL=STYLESHEET HREF="JSP-Styles.css" TYPE="text/css"> </HEAD> <BODY> <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> Shared Access Counts: Page 3</TABLE> <P> <jsp:useBean id="counter" class="cwp.AccessCountBean" scope="application"> <jsp:setProperty name="counter" property="firstPage" value="SharedCounts3.jsp" /> </jsp:useBean> Of SharedCounts3.jsp (this page), <A HREF="SharedCounts1.jsp">SharedCounts1.jsp</A>, and <A HREF="SharedCounts2.jsp">SharedCounts2.jsp</A>, <jsp:getProperty name="counter" property="firstPage" /> was the first page accessed. <P> Collectively, the three pages have been accessed <jsp:getProperty name="counter" property="accessCount" /> times. </BODY> </HTML>
Aug 28
SaleEntry3.jsp Page that uses the SaleEntry bean, using property=”*” to read request parameters and assign them to bean properties
SaleEntry3.jsp Page that uses the SaleEntry bean, using property="*" to read request parameters and assign them to bean properties
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--
Example of using jsp:setProperty and a general association
with the input parameters. See SaleEntry1.jsp
and SaleEntry2.jsp for alternatives.
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>Using jsp:setProperty</TITLE>
<LINK REL=STYLESHEET
HREF="JSP-Styles.css"
TYPE="text/css">
</HEAD>
<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
<TR><TH CLASS="TITLE">
Using jsp:setProperty</TABLE>
<jsp:useBean id="entry" class="cwp.SaleEntry" />
<%-- WARNING! Both the JSWDK 1.0.1 and the Java Web Server
have a bug that makes them fail on automatic
type conversions to double values.
--%>
<jsp:setProperty name="entry" property="*" />
<BR>
<TABLE ALIGN="CENTER" BORDER=1>
<TR CLASS="COLORED">
<TH>Item ID<TH>Unit Price<TH>Number Ordered<TH>Total Price
<TR ALIGN="RIGHT">
<TD><jsp:getProperty name="entry" property="itemID" />
<TD>$<jsp:getProperty name="entry" property="itemCost" />
<TD><jsp:getProperty name="entry" property="numItems" />
<TD>$<jsp:getProperty name="entry" property="totalCost" />
</TABLE>
</BODY>
</HTML>
SaleEntry.java //SaleEntry Bean
package cwp;
/** Simple bean to illustrate the various forms
* of jsp:setProperty.
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class SaleEntry {
private String itemID = "unknown";
private double discountCode = 1.0;
private int numItems = 0;
public String getItemID() {
return(itemID);
}
public void setItemID(String itemID) {
if (itemID != null) {
this.itemID = itemID;
} else {
this.itemID = "unknown";
}
}
public double getDiscountCode() {
return(discountCode);
}
public void setDiscountCode(double discountCode) {
this.discountCode = discountCode;
}
public int getNumItems() {
return(numItems);
}
public void setNumItems(int numItems) {
this.numItems = numItems;
}
// In real life, replace this with database lookup.
public double getItemCost() {
double cost;
if (itemID.equals("a1234")) {
cost = 12.99*getDiscountCode();
} else {
cost = -9999;
}
return(roundToPennies(cost));
}
private double roundToPennies(double cost) {
return(Math.floor(cost*100)/100.0);
}
public double getTotalCost() {
return(getItemCost() * getNumItems());
}
}
Aug 28
SaleEntry1.jsp Page that uses the SaleEntry bean, using explicit Java code to read request parameters and assign them to bean properties.
SaleEntry1.jsp Page that uses the SaleEntry bean, using explicit Java code to read request parameters and assign them to bean properties.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--
Example of using jsp:setProperty with an explicit value
supplied to the "value" attribute. See SaleEntry2.jsp
and SaleEntry3.jsp for alternatives.
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>Using jsp:setProperty</TITLE>
<LINK REL=STYLESHEET
HREF="JSP-Styles.css"
TYPE="text/css">
</HEAD>
<BODY>
<TABLE BORDER=5 ALIGN="CENTER">
<TR><TH CLASS="TITLE">
Using jsp:setProperty</TABLE>
<jsp:useBean id="entry" class="cwp.SaleEntry" />
<jsp:setProperty
name="entry"
property="itemID"
value='<%= request.getParameter("itemID") %>' />
<%
int numItemsOrdered = 1;
try {
numItemsOrdered =
Integer.parseInt(request.getParameter("numItems"));
} catch(NumberFormatException nfe) {}
%>
<jsp:setProperty
name="entry"
property="numItems"
value="<%= numItemsOrdered %>" />
<%
double discountCode = 1.0;
try {
String discountString =
request.getParameter("discountCode");
// Double.parseDouble not available in JDK 1.1.
discountCode =
Double.valueOf(discountString).doubleValue();
} catch(NumberFormatException nfe) {}
%>
<jsp:setProperty
name="entry"
property="discountCode"
value="<%= discountCode %>" />
<BR>
<TABLE ALIGN="CENTER" BORDER=1>
<TR CLASS="COLORED">
<TH>Item ID<TH>Unit Price<TH>Number Ordered<TH>Total Price
<TR ALIGN="RIGHT">
<TD><jsp:getProperty name="entry" property="itemID" />
<TD>$<jsp:getProperty name="entry" property="itemCost" />
<TD><jsp:getProperty name="entry" property="numItems" />
<TD>$<jsp:getProperty name="entry" property="totalCost" />
</TABLE>
</BODY>
</HTML>
SaleEntry.Java //sale entry bean
package cwp;
/** Simple bean to illustrate the various forms
* of jsp:setProperty.
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class SaleEntry {
private String itemID = "unknown";
private double discountCode = 1.0;
private int numItems = 0;
public String getItemID() {
return(itemID);
}
public void setItemID(String itemID) {
if (itemID != null) {
this.itemID = itemID;
} else {
this.itemID = "unknown";
}
}
public double getDiscountCode() {
return(discountCode);
}
public void setDiscountCode(double discountCode) {
this.discountCode = discountCode;
}
public int getNumItems() {
return(numItems);
}
public void setNumItems(int numItems) {
this.numItems = numItems;
}
// In real life, replace this with database lookup.
public double getItemCost() {
double cost;
if (itemID.equals("a1234")) {
cost = 12.99*getDiscountCode();
} else {
cost = -9999;
}
return(roundToPennies(cost));
}
private double roundToPennies(double cost) {
return(Math.floor(cost*100)/100.0);
}
public double getTotalCost() {
return(getItemCost() * getNumItems());
}
}
Aug 28
StringBean.jsp Page that manipulates the StringBean bean with both jsp:useBean (i.e., XML-style) syntax
StringBean.jsp Page that manipulates the StringBean bean with both jsp:useBean (i.e., XML-style) syntax
package cwp;
/** Simple bean to illustrate sharing beans through
* use of the scope attribute of jsp:useBean.
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class AccessCountBean {
private String firstPage;
private int accessCount = 1;
public String getFirstPage() {
return(firstPage);
}
public void setFirstPage(String firstPage) {
this.firstPage = firstPage;
}
public int getAccessCount() {
return(accessCount++);
}
}
Aug 28
RepeatTag.java Custom tag that repeats the tag body a specified number of times
RepeatTag.java Custom tag that repeats the tag body a specified number of times
package cwp.tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
/** A tag that repeats the body the specified
* number of times.
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class RepeatTag 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 RepeatTag: " + ioe);
}
return(EVAL_BODY_TAG);
} else {
return(SKIP_BODY);
}
}
}
RepeatExample.jsp
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!--
Illustration of RepeatTag tag.
Taken from Core Web Programming Java 2 Edition
from Prentice Hall and Sun Microsystems Press,
.
May be freely used or adapted.
-->
<HTML>
<HEAD>
<TITLE>Some 40-Digit Primes</TITLE>
<LINK REL=STYLESHEET
HREF="JSP-Styles.css"
TYPE="text/css">
</HEAD>
<BODY>
<H1>Some 40-Digit Primes</H1>
Each entry in the following list is the first prime number
higher than a randomly selected 40-digit number.
<%@ taglib uri="cwp-taglib.tld" prefix="cwp" %>
<OL>
<!-- Repeats N times. A null reps value means repeat once. -->
<cwp:repeat reps='<%= request.getParameter("repeats") %>'>
<LI><cwp:prime length="40" />
</cwp:repeat>
</OL>
</BODY>
</HTML>
Aug 28
An applet that reads arrays of strings packaged inside a QueryCollection and places them in a scrolling TextArea.
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
/** Applet reads arrays of strings packaged inside
* a QueryCollection and places them in a scrolling
* TextArea. The QueryCollection obtains the strings
* by means of a serialized object input stream
* connected to the QueryGenerator servlet.
*
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* May be freely used or adapted.
*/
public class ShowQueries extends Applet
implements ActionListener, Runnable {
private TextArea queryArea;
private Button startButton, stopButton, clearButton;
private QueryCollection currentQueries;
private QueryCollection nextQueries;
private boolean isRunning = false;
private String address =
"/servlet/cwp.QueryGenerator";
private URL currentPage;
public void init() {
setBackground(Color.white);
setLayout(new BorderLayout());
queryArea = new TextArea();
queryArea.setFont(new Font("Serif", Font.PLAIN, 14));
add(queryArea, BorderLayout.CENTER);
Panel buttonPanel = new Panel();
Font buttonFont = new Font("SansSerif", Font.BOLD, 16);
startButton = new Button("Start");
startButton.setFont(buttonFont);
startButton.addActionListener(this);
buttonPanel.add(startButton);
stopButton = new Button("Stop");
stopButton.setFont(buttonFont);
stopButton.addActionListener(this);
buttonPanel.add(stopButton);
clearButton = new Button("Clear TextArea");
clearButton.setFont(buttonFont);
clearButton.addActionListener(this);
buttonPanel.add(clearButton);
add(buttonPanel, BorderLayout.SOUTH);
currentPage = getCodeBase();
// Request a set of sample queries. They
// are loaded in a background thread, and
// the applet checks to see if they have finished
// loading before trying to extract the strings.
currentQueries = new QueryCollection(address, currentPage);
nextQueries = new QueryCollection(address, currentPage);
}
/** If you press the "Start" button, the system
* starts a background thread that displays
* the queries in the TextArea. Pressing "Stop"
* halts the process, and "Clear" empties the
* TextArea.
*/
public void actionPerformed(ActionEvent event) {
if (event.getSource() == startButton) {
if (!isRunning) {
Thread queryDisplayer = new Thread(this);
isRunning = true;
queryArea.setText("");
queryDisplayer.start();
showStatus("Started display thread...");
} else {
showStatus("Display thread already running...");
}
} else if (event.getSource() == stopButton) {
isRunning = false;
showStatus("Stopped display thread...");
} else if (event.getSource() == clearButton) {
queryArea.setText("");
}
}
/** The background thread takes the currentQueries
* object and every half-second places one of the queries
* the object holds into the bottom of the TextArea. When
* all of the queries have been shown, the thread copies
* the value of the nextQueries object into
* currentQueries, sends a new request to the server
* in order to repopulate nextQueries, and repeats
* the process.
*/
public void run() {
while(isRunning) {
showQueries(currentQueries);
currentQueries = nextQueries;
nextQueries = new QueryCollection(address, currentPage);
}
}
private void showQueries(QueryCollection queryEntry) {
// If request has been sent to server but the result
// isn't back yet, poll every second. This should
// happen rarely but is possible with a slow network
// connection or an overloaded server.
while(!queryEntry.isDone()) {
showStatus("Waiting for data from server...");
pause(1);
}
showStatus("Received data from server...");
String[] queries = queryEntry.getQueries();
String linefeed = "\n";
// Put a string into TextArea every half-second.
for(int i=0; i
Aug 28
FilterTag.java Custom tag that modifies the tag body
FilterTag.java Custom tag that modifies the tag body
package cwp.tags;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
import cwp.*;
/** A tag that replaces <, >, ", and & with their HTML
* character entities (<, >, ", and &).
* After filtering, arbitrary strings can be placed
* in either the page body or in HTML attributes.
* <P>
* Taken from Core Web Programming Java 2 Edition
* from Prentice Hall and Sun Microsystems Press,
* .
* May be freely used or adapted.
*/
public class FilterTag extends BodyTagSupport {
public int doAfterBody() {
BodyContent body = getBodyContent();
String filteredBody =
ServletUtilities.filter(body.getString());
try {
JspWriter out = body.getEnclosingWriter();
out.print(filteredBody);
} catch(IOException ioe) {
System.out.println("Error in FilterTag: " + ioe);
}
// SKIP_BODY means we're done. If we wanted to evaluate
// and handle the body again, we'd return EVAL_BODY_TAG.
return(SKIP_BODY);
}
}
