Developing for the J2EE Tomcat Platform
Table of Contents
1.
Java Server Pages
2.
JavaBeans
3.
Tag Libraries
4.
Introduction to Struts
5.
Advanced Struts
6.
Enterprise JavaBeans
7.
A Case Study
Chapter 1. Introduction to J2EE
Servlets and Java Server Pages
What is J2EE?
Java Server Pages
Java Servlets: A bit of history
JSP Syntax
An Example with JBoss and Tomcat
MyGreeting: A simple web application
Exercises
Goals
After completing this chapter, the student will be able to
explain Servlets and Java Server Pages (JSPs) and their roles in
developing web applications.
have JBoss deploy with the Tomcat container in an integrated virtual
machine.
create JSPs for use in systems producing dynamically generated
HTML.
Prerequisites
The student will need to be famliar with web browsers, an understanding of
HTML, and familiarity with Java and its use in programming.
Objectives
This chapter is presented to provide an understanding of the role that Servlets
and Java Server Pages play in the web application development process and
to understand what J2EE is.
What is J2EE?
J2EE (Java 2 Enterprise Edition) is a specification for developing enterprise and
distributed applications from JavaSoft (Sun Microsystems). J2EE is not one thing; it
encompasses a large set of technologies:
JavaServer Pages (JSP)
Servlets
Enterprise JavaBeans (EJB)
JDBC
support for XML
Java Messaging
Java Transaction Support
JavaMail
Java support for CORBA
In this course, we will talk about JSP, servlets, EJB, JDBC, and touch on JNDI.
What can using these technologies accomplish?
J2EE is useful for creating web applications like Yahoo! Mail, a web-based stock trading
system such as E*TRADE, or an online auction house like eBay. Anytime there is a need
for many people to access a collection of data in a distributed manner, an implementation
of the J2EE specification can provide a solution.
Where is J2EE?
Since J2EE is a specification, it isn't located anywhere. Instead vendors make their
products adhere to the J2EE specification.
Examples of the vendors offering J2EE compliant products are
Netscape/AOL iPlanet
BEA WebLogic
IBM WebSphere
The JBoss Group's JBoss
In this course, we will concentrate on JBoss, which is a free, open-source J2EE server.
The JBoss server itself is written in Java, so it can run on Windows, Linux, Mac OS X,
Solaris, or any other platform which fully supports the Java virtual machine.
Java Server Pages (JSP) are Sun's solution to the generation of dynamic HTML. With
JSPs, you can generate HTML on the fly, which is important because
the content of the HTML may depend upon user submitted data
the information represented by the HTML is dynamic by nature
the HTML may be customizable on a per user basis
JSPs are HTML-like pages that can contain a mixture of HTML tags, data, and Java code.
Here is an example of a JSP that contains a simple for loop to count to 10:
code/Chapter1/counter/counter.jsp
<%@ page language="java" %> <HTML>
<BODY> <%
for (int counter = 1; counter <= 10; counter++) { %>
<%= counter %> Mississippi,<BR> <%
} %>
<B>Ready or not, here I come!</B> </BODY>
</HTML>
We then deploy this on a web server that knows how to handle JSPs. (We'll see how to
deploy it later in this chapter.) The JSP will be mapped to a specific web address on that
server, and when a user comes along and types in that web address, the web server will
find this JSP, dynamically compile the Java code in it, run it, merge it with the HTML
tags that are interspersed around the Java code, and output an HTML page back to the
user's browser. The generated HTML will look like this:
<HTML> <BODY> 1 Mississippi,<BR> 2 Mississippi,<BR> 3 Mississippi,<BR> 4 Mississippi,<BR>
5 Mississippi,<BR> 6 Mississippi,<BR> 7 Mississippi,<BR> 8 Mississippi,<BR> 9 Mississippi,<BR> 10 Mississippi,<BR>
<B>Ready or not, here I come!</B> </BODY>
</HTML>
Java Servlets: A bit of history
Servlets are pure Java objects that generate HTML by writing it to a stream. The files do
not contain any HTML tags; they simply contain Java code which write out HTML (as
strings) to produce the page that is sent to the user's browser. Historically, this used to be
the only way to generate dynamic content in Java, but it is quite painful to develop any
large scale application with a bunch of servlets running around doing println()
statements. This is why Sun invented JSPs in the first place: to compete with the
ease-of-development of Microsoft's ASP files, which could -- you guessed it -- mix HTML tags
and code in a single file.
JSPs and servlets are two different ways to accomplish the same goal: generating
dynamic HTML pages using Java code. One puts Java code in your HTML, and one puts
HTML in your Java code. Functionally, they are equivalent. In fact, under the covers, the
web server takes a JSP and converts it to the corresponding servlet and dynamically
compiles it.
Here is a Java servlet that produces the same content as the JSP we just saw above:
code/Chapter1/counter/counterAsServlet.java
import javax.servlet.*; import java.io.*;
import java.util.*;
public class SimpleServlet extends GenericServlet { public void service(ServletRequest request,
ServletResponse response)
throws ServletException, IOException { response.setContentType("text/html");
code/Chapter1/counter/counterAsServlet.java
printWriter pw = response.getWriter(); pw.println("<HTML>");
pw.println("<BODY>");
for(int counter = 1; counter <= 10; counter++) { pw.println(counter + " Mississippi, <BR>"); }
pw.println("<B>Ready or not, here I come!</B>"); pw.println("</BODY>");
pw.println("</HTML>"); pw.close();
} }
You can still write Java servlets manually if you want to, and many people still swear by
them. However, JSPs are more flexible, and as we'll see in later chapters, can be
combined with other features to create a powerful templating engine. We will not be
writing servlets in this course, although we will see them sneak in behind the scenes in
chapter 4.
JSP Syntax
Directives
JSPs live in an object called a container, which is essentially a server. JSPs can define
information for the container with directives.
Here is what directives look like in a general form:
<%@ directive attribute="someValue" attribute="anotherValue" ... %>
There are three directives:
<%@ page ... %> specifies information that affects the page
<%@ include ... %> includes a file at the location of the include directive
(parsed)
<%@ taglib ... %> allows the use of custom tags in the page
<%@ page language="java" %> will always be the first line of every JSP file.
Declarations
Declarations are used to specify supplemental methods and variables. You can think of
these are the page's private functions; they can only be called by the JSP where they are
defined, or by another JSP that includes it (using the <@ include > directive).
Here is a sample declaration:
<%!// this integer can be used anywhere in this JSP page private int myVariable = -1;
// this function can be called from anywhere in this JSP page public boolean isPositive() {
return ( myVariable > 0 ); }
%>
Scriptlets
Scriptlets are bits of Java code. They can do anything (the full power of Java is available
in every JSP), but they will most likely concentrate on generating HTML code or setting
up variables to be part of later expressions (see below).
The first JSP we saw above, counter.jsp, contained a scriptlet with a for loop.
Expressions
Expressions are special-purpose mini-scriptlets used for evaluating expressions. This
could be something as simple as outputting the value of a variable, or a more complicated
Java expression, like calling a function and outputting the result.
The JSP example counter.jsp also contained an expression:
<%= counter %>Note that counter is defined as an int, but we do not need to explicitly convert it to a
string. Expressions are implicitly converted to strings when they are output. (The
println() function works the same way; it can take pretty much anything and print it.That makes sense if you think about it. Remember that JSPs automatically get converted
to Java servlets under the covers. So an expression like this in a JSP file is converted to a
println statement in a servlet that you never see. So anything println can print, anexpression can contain, without any explicit conversion.)
An Example with JBoss and Tomcat
Now lets create a web application using JBoss with Tomcat. JBoss is an open-sourced
J2EE server from the JBoss Group (
www.jboss.org
). It provides support for integrating
Tomcat, which is the open-sourced Servlet and JSP engine from the Apache Group's
Jakarta project (
jakarta.apache.org
).
Note: If JBoss with Tomcat is not already installed, the instructor will provide assistance
with getting it installed.
The files for a J2EE web application are placed in a web application archive file (.war
extension). Inside the web application archive are JSPs, HTML pages, .properties files,
XML configuration files, images, and class files, as well as any customized data files that
might need to be included. At a minimum, the web application archive will consist of a
WEB-INF folder at the top level. Inside the WEB-INF folder will be a web.xml file. The web.xml file provides the J2EE server with information specific to the web applicationcontained in the same web application archive. For example, it provides the name for the
default page to serve, if one is not specified.
MyGreeting: A simple web application
Do this:
1. Create a directory named MyGreeting
2. Within the MyGreeting directory, create a subdirectory named WEB-INF
(capitalization matters, so be precise, and that's a dash, not an underscore)
code/Chapter1/MyGreeting
MyGreeting | +-- HelloWorld.jsp (*) | +-- WEB-INF | +-- web.xml (*) (*) denotes a file3. Create a JSP file named MyGreeting/HelloWorld.jsp
4. Add the following text to the HelloWorld.jsp file:
Code/Chapter1/MyGreeting/HelloWorld.jsp
<%@ page language="java" %> <HTML>
<BODY> <%
for (int counter = 1; counter <= 10; counter++) { %>
Code/Chapter1/MyGreeting/HelloWorld.jsp
Hello World!<BR> <% } %> </BODY> </HTML>5. Create the web.xml file in MyGreeting/WEB-INF/web.xml
6. Add the following text to web.xml:
code/Chapter1/MyGreeting/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app> </web-app>
7. Drop to a command line and change to MyGreeting directory
8. Create the web application archive using the command-line jar utility:
c:\j2ee\code\Chapter1\MyGreeting> jar cvf MyGreeting.war *.jsp WEB-INF
9. Copy MyGreeting.war to the deploy folder in your JBoss installation:
c:\j2ee\code\Chapter1\MyGreeting> copy MyGreeting.war c:\j2ee\jboss\deploy\
10. Start JBoss by running the run.bat script provided in the bin folder of the JBoss
installation. Because JBoss relies on relative paths to set up its CLASSPATH, this
is a two-step process. First, change to the jboss/bin/ directory, then execute
run.bat. Also, be sure to specify the tomcat argument on the command line sothat it also starts the Tomcat servlet engine.
c:\j2ee\code\Chapter1\MyGreeting> cd c:\j2ee\jboss\bin\ c:\j2ee\jboss\bin> run.bat tomcat
11. Open a web browser and go to
http://localhost:8080/MyGreeting/HelloWorld.jsp
Exercises
Exercise 1. Current time
Create a web application that displays the current time in a web page. Provide a link
inside the web page to reload the page with the an updated time. Use JSPs in order to
produce the dynamic content.
JavaBeans
What is Scope?
Every JSP has 5 implicit objects
The request-response cycle
A JSP using the
requestand
responseobjects
Three parts of a web application
A JSP using the
pageContext,
session, and
applicationimplicit objects
Using Java Classes with JSP
FirstBean: a simple JavaBean
Accessor and mutator methods
SecondBean: a JavaBean with accessor and mutator methods
What is Persistence?
SerializableBean: a JavaBean with Persistence
Exercises
Goals
After completing this chapter, the student will be able to
explain scope.
discuss implicit objects.
make a JavaBean.
Prerequisites
In order to complete this chapter successfully, the student must have
a basic understanding of the request-response cycle.
an understanding of JSP directives (<%@), scriptlets (<%), expressions
(<%=), and declarations (<%!).
a basic understanding of how to construct a JSP.
Objectives
The purpose of this chapter is to provide the student with the necessary
information about implicit objects and JavaBeans.
What is Scope?
Scope is the idea that an object belongs to a certain part of an application. The five main
scopes of a web application are request, response, page, session, and application. This
means that an object may be a part of a request, a response, an individual page, a session,
or an instance of the application. For example, if we said, "the employee object has
session scope," we would mean that the employee object only existed within a certain
session.
This section discusses the implicit objects that represent the request, response, page,
session, and application scopes. In JSPs, implicit objects are created by the JSP
environment, so the developer does not need to initialize an implicit object. Implicit
objects can only be used in JSP scriptlets and expressions.
Implicit object Description
request
The ServletRequest or HttpServletRequest being serviced
response
The Servlet Response or HttpServletResponse that will receive the
generated HTML output
pageContext
The PageContext object for this page. This object is a central respiratory
for attribute data for the page, request , session and application
session
If the Jsp Page uses an HttpSession, it is availabele here under the name
session
application
The Servlet context Object
Out
The character output stream used to generate the output HTML
ConfigThe Servletconfig object for this servlet context
Page
A Reference to the jsp page itself.
Exception
An uncaught exception that causes the error page to be invoked.this
variable is available only to pages with isErrorpage=”true”
The request-response cycle
A very basic, generic request-response cycle consists of two parts. The request is where
the client asks for data from the server, and response is where the server sends data to the
client.
Capabilities of the
requestand
responseobjects
In JSPs, the request-response cycle is represented mainly by the request and response
objects. The request object handles the information sent from the client and the
Methods involved in the request
return type method name
description
HttpSession getSession()
returns the session associated with
the request
String getHeader(String headerName)
returns the value associated with the
header name of the request
Enumeration getHeaderNames()
returns all the header names
associated with a request
Cookie[] getCookies()
returns the cookies associated with a
request
Object getAttribute(String attributeName)
returns the object that is paired with
an attribute's name
void setAttribute(String nameOfTheAttribute, Object valueOfTheAttribute)
sets an attribute named
nameOfTheAttribute to the value of valueOfTheAttribute
Methods involved in the response
return
type
method name
description
void addCookie(Cookie cookie)
adds the specified cookie to the
response
void addHeader(String headerName, Stringvalue)
adds the header to the response
void sendError(int statusCode) throws IOExceptionsends a predefined error message
back to the client
void sendRedirect(String newURL) throws IOException
redirects the client browser to a
different URL
A JSP using the
requestand
responseobjects
code/Chapter2/RequestResponse/requestresponse.jsp
<%@ page language="java" %> <HTML>
code/Chapter2/RequestResponse/requestresponse.jsp
character encoding = <%= response.getCharacterEncoding() %> <br/><br/>
Headers <br/><br/>
<% java.util.Enumeration headerNames = request.getHeaderNames(); while(headerNames.hasMoreElements()) {
String headerName = (String)headerNames.nextElement(); String header = (String)request.getHeader(headerName); %> <%= headerName %> = <%=header%> <br/> <% } %> </BODY> </HTML>
Three parts of a web application
Information in a web application can be stored in the application scope, the session scope,
and the page scope. The page scope refers to all information that only pertains to a
specific instance of a given page. The server keeps the page-specific information as long
as the page exists. The session scope contains information pertaining to a session
instance. The application scope contains information that is available to all sessions in the
application, as long as the application is running.
The
pageContext,
sessionand
applicationobjects
A programmer can access information stored in the page, the session, and the application
scope, using the pageContext, session, and application objects, respectively.
return type
method name
description
Object findAttribute(String attributeName)
searches the page, session,
application and request scopes for
an attribute named attributeName - it
returns the attribute or null, if the
attribute does not exist
Object getAttribute(String attributeName)
returns the object that is paired with an
attribute's name
void setAttribute(String nameOfTheAttribute, Object valueOfTheAttribute)sets an attribute named
nameOfTheAttribute to the value of valueOfTheAttribute
HttpServletRequest getRequest()
returns the request object associated
with the page
HttpServletResponse getResponse()
returns the response object associated
with the page
Basic
sessionmethods
return
type
method name
description
Object getAttribute(String attributeName)
returns the object that is paired with an
attribute named attributeName
void setAttribute(String nameOfTheAttribute, Object valueOfTheAttribute)
sets an attribute named
nameOfTheAttribute to the value of valueOfTheAttribute
String[] getAttributeNames()
returns an array of the names of the
attributes for a given session
Basic
applicationmethods
return type method name
description
Object getAttribute(String attributeName)
returns the object that is paired with
an attribute's name
void setAttribute(String nameOfTheAttribute, Object valueOfTheAttribute)
sets an attribute named
nameOfTheAttribute to the value of valueOfTheAttribute
Enumeration getAttributeNames()
returns an array of the names of the
attributes for a given application
Here is a JSP that uses the pageContext, session, and application implicit objects.
code/Chapter2/ImplicitObjects/implicitobjects.jsp
<%@ page language="java" %>
<% if (pageContext.getAttribute("pageCount")==null) {
pageContext.setAttribute("pageCount", new Integer(0)); } if (session.getAttribute("sessionCount")==null) { session.setAttribute("sessionCount",new Integer(0)); } if (application.getAttribute("appCount")==null) { application.setAttribute("appCount",new Integer(0)); } %> <HTML> <BODY>
<% Integer count = (Integer)pageContext.getAttribute("pageCount"); pageContext.setAttribute("pageCount", new
Integer(count.intValue()+1));
Integer count2 = (Integer)session.getAttribute("sessionCount"); session.setAttribute("sessionCount",new
Integer(count2.intValue()+1));
Integer count3 = (Integer)application.getAttribute("appCount"); application.setAttribute("appCount",new
Integer(count3.intValue()+1)); %>
Page Count = <%= pageContext.getAttribute("pageCount")%>
<br/>Session count = <%= session.getAttribute("sessionCount")%> <br/>Application count = <%= application.getAttribute("appCount")%> <br/>Time = <%= new java.sql.Time(System.currentTimeMillis()) %> </BODY>
</HTML>
Using Java Classes with JSP
Not all the code for a JSP needs to be written in the JSP itself. In fact, in good coding
practice no code should be found in the JSP. This provides greater separation between the
clients' view of the application and the logic of the application. Separation between logic
and presentation means a more easily modifiable application.
jsp:useBean creates an instance of a specified class that is usable in a JSP. The instance
of a Java class in a JSP is commonly referred to as a bean or a JavaBean. In order to
create an instance, named greeter, of a custom class named Greetings with a package
named thePackage, a JSP must state the following:
<jsp:useBean id="greeter" class="thePackage.Greetings" scope="session" />
The scope attribute specifies whether the instantiated object has a page, session, or
application scope. The JSP can then make calls to the object's methods in scriptlets and/or
declarations:
<% greeter.setNameOfPersonToBeGreeted("Jill"); greeter.setLanguage("Spanish"); %> <%= greeter.sayHello() %> <%= greeter.sayGoodBye() %>Naming Confusion: Two Types of JavaBeans
It is important to distinguish between a JavaBean used in a GUI development tool and a
JavaBean used in a server-side application. This chapter discusses the later type of
JavaBean. A JavaBean, or sometimes just called a bean, is basically an instance of a Java
class. The two main characteristics of a server-side JavaBean are that accessor and
mutator methods should be provided for all properties in the Java class and that the
JavaBean may be persistent.
JavaBeans are normally deployed as part of a package. For this chapter, we will put our
JavaBeans in the com.masslight.beans package.
When deploying a JavaBean as part of a web application, the package structure is
recreated as a nested directory structure within the WEB-INF/classes/ directory. So our
com.masslight.beans package will become the directory pathWEB-INF/classes/com/masslight/beans/, and our Java classes will go inside that
directory.
FirstBean: a simple JavaBean
Do this:
1. Create the following directory structure. Create a FirstBean directory to hold all
of the files for this web application, then within that, create a WEB-INF directory,
then within that create a classes directory, then com, then masslight, then
beans. Whew!code/Chapter2/FirstBean
FirstBean | +-- beanExample.jsp (*) | +-- WEB-INF | +-- web.xml (*) | +-- classes | +-- com | +-- masslight | +-- beans | +-- GreeterBean.java (*) (*) denotes a file2. Create the JSP in the FirstBean directory:
code/Chapter2/FirstBean/beanExample.jsp
<%@ page language="java" %> <html>
<head><title>Hello Example</title></head> <body>
<jsp:useBean id="greeter" class="com.masslight.beans.GreeterBean" scope="session"/>
<%= greeter.sayHello() %> </body>
</html>
3. Create the web.xml file in the WEB-INF directory:
code/Chapter2/FirstBean/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app> </web-app>
4. Create the Java file in the FirstBean/WEB-INF/classes/com/masslight/beans
code/Chapter2/FirstBean/WEB-INF/classes/com/masslight/beans/GreeterBean.java
package com.masslight.beans; public class GreeterBean { public String sayHello() { return("Hello, World!"); }
}
5. Change to the beans directory and compile the Java file with javac, Sun's
command-line Java compiler:
c:\j2ee\code\Chapter2\FirstBean\WEB-INF\classes\com\masslight\beans> javac *.java
6. Change back to the FirstBean directory and create the .war file, using the jar
utility like you did in the previous chapter
c:\j2ee\code\Chapter2\FirstBean> jar cvf FirstBean.war *.jsp WEB-INF
7. Deploy the web application by copying the .war file to the JBoss deployment
directory
c:\j2ee\code\Chapter2\FirstBean> copy FirstBean.war c:\j2ee\jboss\deploy\
8. Test the application by going to
http://localhost:8080/FirstBean/beanExample.jsp
Accessor and mutator methods
JavaBeans require properties to have accessor and mutator methods. A property is another
name for a class-wide variable. Accessors provide a standardized way of accessing the
value of a property. Mutators provide a standard way to modify the value of a property. In
fact, it is good coding practice to provide and use accessor and mutator methods for
properties in all Java classes. To make the accessor and mutator methods for a property,
the standard practice is to prepend the name of the property with the word 'get' for the
get method name and 'set' for the set method name. In the accessor and mutator methods'
names, the property name is capitalized, though the property's name should be declared in
the lower case. An example of the accessor and mutator methods for a simple variable of
type variable_type and name exampleVariable would be:
public void setExampleVariable(variable_type value) public variable_type getExampleVariable()
If the variable_type is boolean, the set method would be the same and the get method
would be:
public boolean isExampleVariable()
If the property is an array, then the getter and setter methods are:
public variable_type[] getExampleVariable()
public variable_type getExampleVariable(int location_in_array) public void setExampleVariable(variable_type[])
public void setExampleVariable(int location_in_array, variable_type value)
SecondBean: a JavaBean with accessor and mutator methods
Do this:
1. Create the directory structure. Create a SecondBean directory to hold all the files
for this web application. Within SecondBean, the directory structure is the same
as it was for FirstBean.
code/Chapter2/SecondBean
SecondBean | +-- beanExample.jsp (*) | +-- WEB-INF | +-- web.xml (*) | +-- classes | +-- com | +-- masslight | +-- beanscode/Chapter2/SecondBean
|
+-- NumberBean.java (*) (*) denotes a file
2. Create the JSP in the SecondBean directory:
code/Chapter2/SecondBean/beanExample.jsp
<%@ page language="java" %>
<jsp:useBean id="number" class="com.masslight.beans.NumberBean" scope="session"/>
<html>
<head><title>Second Bean Example</title></head> <body>
JavaBean state starts at <%= number.getIntegerProperty() %> <% number.setIntegerProperty(2); %>
<br> JavaBean state is now <%= number.getIntegerProperty() %> </body>
</html>
3. Create the web.xml file in WEB-INF
code/Chapter2/SecondBean/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app> </web-app>
4. Create the Java file in WEB-INF/classes/com/masslight/beans/
code/Chapter2/SecondBean/WEB-INF/classes/com/masslight/beans/NumberBean.java
package com.masslight.beans; public class NumberBean {
code/Chapter2/SecondBean/WEB-INF/classes/com/masslight/beans/NumberBean.java
private int integerProperty = 1; public int getIntegerProperty() { return integerProperty;
}
public void setIntegerProperty(int newInteger) { integerProperty = newInteger;
} }
5. Compile the Java classes, in the same way you did with FirstBean
6. Create the .war file, in the same way you did with FirstBean. Call it
SecondBean.war
7. Deploy the web application by copying SecondBean.war to the JBoss
deployment directory
8. Test the application at
http://localhost:8080/SecondBean/beanExample.jsp
What is Persistence?
The properties of a bean can be saved and then retrieved at a later time - in other words, a
bean can be persistent. In order to be persistent, a JavaBean needs to implement the
java.io.Serializable interface. The java.io.Serializable interface does not haveany methods to implement. It is used to indicate that the class that implements it can be
saved and retrieved. To learn how to save and retrieve a bean, please look at the
following example.
SerializableBean: a JavaBean with Persistence
Do this:
1. Create the directory structure. Create a SerializableBean directory; within that,
the structure is the same as FirstBean and SecondBean.
code/Chapter2/SerializableBean
SerializableBean |
code/Chapter2/SerializableBean
+-- firstPage.jsp (*) | +-- secondPage.jsp (*) | +-- WEB-INF | +-- web.xml (*) | +-- classes | +-- com | +-- masslight | +-- beans | +-- SerializableBean.java (*) (*) denotes a file2. Create 2 JSPs in the SerialiableBean directory:
code/Chapter2/SerializableBean/firstPage.jsp
<%@ page language="java" %>
<jsp:useBean id="theBean" class="com.masslight.beans.SerializableBean" scope="page" />
<html>
<title>Serialized bean, Page One</title> <body> <br> <%= theBean.getIntegerProperty() %> <% theBean.setIntegerProperty(8+theBean.getIntegerProperty()); %> <br> <%= theBean.getIntegerProperty() %> <% theBean.save(theBean, "theBeanFile.ser"); %> <br> <a href="http://localhost:8080/SerializableBean/secondPage.jsp">click here</a> </body> </html>
code/Chapter2/SerializableBean/secondPage.jsp
<%@ page language="java" %>
<jsp:useBean id="saver" class="com.masslight.beans.SerializableBean" scope="session"/>
<html>
<title>Serialized bean, Page Two</title> <body> <% com.masslight.beans.SerializableBean anotherBean = (com.masslight.beans.SerializableBean)saver.retrieve("theBeanFile.ser"); %> <%= anotherBean.getIntegerProperty() %> <br> <% anotherBean.setIntegerProperty(8+ anotherBean.getIntegerProperty()); %> <%= anotherBean.getIntegerProperty() %> </body> </html>
3. Create the web.xml file in WEB-INF
code/Chapter2/SerializableBean/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app> </web-app>
4. Create the Java file in WEB-INF/classes/com/masslight/beans/
code/Chapter2/SerializableBean/WEB-INF/classes/com/masslight/beans/SerializableBean.java
package com.masslight.beans; import java.beans.*; import java.io.Serializable; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.FileInputStream;code/Chapter2/SerializableBean/WEB-INF/classes/com/masslight/beans/SerializableBean.java
import java.io.ObjectInputStream;
public class SerializableBean implements Serializable { private int integerProperty=8;
public int getIntegerProperty() { return integerProperty;
}
public void setIntegerProperty(int newInteger) { integerProperty= newInteger;
}
public boolean save(Object object, String file_name) { boolean status = true;
try{
FileOutputStream fos; ObjectOutputStream oos;
fos = new FileOutputStream(file_name); oos = new ObjectOutputStream(fos); oos.writeObject(object);
oos.close(); }
catch (Exception e) { status = false;
System.out.println("Error with saving: " + e.toString()); }
return status; }
public Object retrieve(String file_name) { Object object = new Object();
try {
FileInputStream fis; ObjectInputStream ois;
fis = new FileInputStream(file_name); ois = new ObjectInputStream(fis); object = ois.readObject();
ois.close(); }
catch (Exception e) {
System.out.println("Error with retrieval: " + e.toString()); }
return object; }}
5. Compile the Java file.
6. Create SerializableBean.war
7. Deploy
Exercises
Exercise 1. Application vs. session
Make a JSP that displays the last time it was ever hit by anyone, and the last time it has
been hit by you personally. If it has never been hit by anyone before, it should display
"This application has never been used before." If this is your first time, it should display
"This is your first time using this application." (Hint: use the application and session
objects.
Exercise 2. Calculator
Make a JavaBean that does simple arithmetic. The application should consist of a JSP
page and a JavaBean. The JavaBean should provide methods, that given two numbers,
produce the sum, the difference, the product, and the quotient. The JavaBean should then
produce output for the JSP similar to the following screen shot. The calls to the JavaBean
methods from the JSP should look like this:
<%= calculator.add(1, 1) %><br> <%= calculator.subtract(4, 2) %><br> <%= calculator.multiply(4, 5) %><br> <%= calculator.divide(30, 6) %>
Chapter 3.
Tag Libraries
What Are Tags?
Using Tags in JSP
SimpleTag: a simple tag-based web application
Tag Attributes
AttributeTag: using attributes in tag libraries
Using Scope Objects in Tags
Exercises
Goals
After completing this chapter, the student will be able to
make a simple custom tag.
make a complex custom tag.
Prerequisites
In order to complete this chapter successfully, the student must understand
JSP directives.
how to construct a JSP.
how to construct and call JavaBeans.
Objectives
The purpose of this chapter is to provide the student with the necessary
information about tags and tag libraries.
What Are Tags?
Tags provide another way for a JSP developer to separate the presentation of an
application from the logic of the application. The implementation of a tag differs from the
implementation of a JavaBean. A tag's class must implement methods unique to tag
classes in order for the tag to be executed properly in the JSP. Also, the tags in an
application require a tag library descriptor XML file that contains information about each
of the tags. A tag class extends javax.servlet.jsp.tagext.TagSupport or
javax.servlet.jsp.tagext.BodyTagSupport.
Using Tags in JSP
In a Java Server Page, a tag is initialized with a declaration that looks like this:
<%@ taglib uri="WEB-INF/lib/tag_library_name.tld" prefix="prefix_name" %>
The tag_library_name.tld, used in the declaration of the tag, is the name of the tag
library that has the information about the tag called tag_name. In JBoss, the
tag_library_name.tld must be located in the /WEB-INF/lib pathway in order to be
located by the JBoss engine. To use a very simple tag in the JSP:
<prefix_name:tag_name/>
A tag can contain a body:
<prefix_name:tag_name>
this is called the body of the tag </prefix_name:tag_name>
A tag can also have attributes:
<prefix_name:tag_name attributeOne="hey" />
Creating a simple tag class
the class should extend javax.servlet.jsp.tagext.TagSupport
should override the method called public int doStartTag() extends
JspTagException {
can override the method called public int doEndTag() extends
JspTagException {
usually does not need to override public void release()
SKIP_BODY versus EVAL_BODY_INCLUDE and SKIP_PAGE versus EVAL_PAGE
SKIP_BODY is returned at the end of doStartTag to tell the JSP to not output the content
contained in the body of the tag. The EVAL_BODY_INCLUDE is returned at the end of the
doStartTag if the content in the body of the tag should be outputted. The SKIP_PAGE isreturned from the doEndTag to tell the JSP to skip the rest of the content of the JSP, while
the EVAL_PAGE signifies that the JSP should evaluate the rest of the contents of the page.
The default values returned are SKIP_BODY and EVAL_PAGE.
doStartTag
Called when the open tag is read in the JSP - returns either SKIP_BODY
or EVAL_BODY_INCLUDE
doEndTag
Called when the close tag is called in the JSP - returns either SKIP_PAGE
or EVAL_PAGE
release
Called when the JSP is finished with the tag - resets the state of the tag
The tag library descriptor file helps a JSP map a tag to a Java class. It is an XML file with
a .tld suffix.
Elements used in the .tld file to describe tags:
taglib
signifies that a tag library will be described - required
tlibversionthe tag library version - required
jspversion
the version of JSP that will be used
shortnamethe name of the tag library - required
uri
the Uniform Resource Identifier for the tag library
infothe comment tag for the developer
tag
signifies that a tag located in the taglib will be described - see
following table for elements of a tag
Elements used in the tag tag:
name
the name of the tag - required
tagclass
the path information to the tag's class - required
teiclass
the path information of the subclass of TagExtraInfo - this is not
discussed in this chapter
bodycontent
specifies the content type of the tag - can be empty, JSP, or
tagdependent - empty means that the tag has no body, JSP means
that there is a body that can interpreted as JSP, and tagdependent
means that the tag will interpret the body as non-JSP content
info
for comments
attribute
signifies that an attribute of the tag will be described - see
following table
Elements used in the attribute tag
name
the name of the attribute that the tag might need in the declaration
- required
required
boolean value to specify if the attribute is required - can be either
true or falsertexprvalue
specifies if the attribute can take a scriptlet expression as a value,
which allows the attribute's value to determined when the attribute
is set - if this element is not specified, the value is false - can be
either true or false
SimpleTag: a simple tag-based web application
Do this:
1. Create the directory structure. Create a SimpleTag directory, then create the usual
WEB-INF and classes, then create the directory structure that represents thepackage structure, which in this example is
com.masslight.tagExampleClasses.
code/Chapter3/SimpleTag
SimpleTag | +-- tagExample.jsp (*) | +-- build.xml (*) | +-- WEB-INF | +-- web.xml (*) | +-- tagExampleLib.tld (*) | +-- classes | +-- com | +-- masslight | +-- tagExampleClasses | +-- HelloWorldTag.java (*) (*) denotes a file2. Create the JSP in the SimpleTag directory
code/Chapter3/SimpleTag/tagExample.jsp
<%@ page language="java" %> <!-- declare the tag -->
<%@ taglib uri="WEB-INF/tagExampleLib.tld" prefix="greeter" %> <html>
<body>
<!-- use the tag --> <greeter:Hello/> </body>
3. Create the web.xml file in WEB-INF
code/Chapter3/SimpleTag/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <taglib> <taglib-uri>/WEB-INF/tagExampleLib.tld</taglib-uri> <taglib-location>/WEB-INF/tagExampleLib.tld</taglib-location> </taglib> </web-app>
4. Create the Java file in WEB-INF/classes/com/masslight/tagExampleClasses/
code/Chapter3/SimpleTag/WEB-INF/classes/com/masslight/tagExampleClasses/HelloWorldTag.java
package com.masslight.tagExampleClasses; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*;public class HelloWorldTag extends javax.servlet.jsp.tagext.TagSupport { public int doStartTag() throws JspException {
try {
pageContext.getOut().print("Hello, World!"); } catch (Exception ex) {
throw new JspException("IO problems"); }
return SKIP_BODY; }
}
5. Create the tag library descriptor file in WEB-INF. This maps each tag used in
tagExample.jsp to a specific Java class, which in this example iscom.masslight.tagExampleClasses.HelloWorldTag.
code/Chapter3/SimpleTag/WEB-INF/tagExampleLib.tld
code/Chapter3/SimpleTag/WEB-INF/tagExampleLib.tld
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>utility</shortname> <info>
A simple tag library for the examples </info> <tag> <name>Hello</name> <tagclass>com.masslight.tagExampleClasses.HelloWorldTag</tagclass> <bodycontent>empty</bodycontent> <info>
Print Hello World </info>
</tag> </taglib>
6. Finally, add the build.xml file, which we will use to automate building and
deploying the web application. build.xml goes in the root SimpleTag directory,
next to the JSPs.
code/Chapter3/SimpleTag/build.xml
<project name="SimpleTag" default="dist" basedir="."> <!-- set global properties for this build -->
<property environment="env"/> <property name="top" value="."/> <property name="src" value="."/>
<property name="build" value="build"/> <property name="dist" value="dist"/>
<property name="war_dir" value="${dist}/lib"/>
<property name="war_file" value="${war_dir}/SimpleTag.war"/> <property name="webinf" value="${top}/WEB-INF"/>
<property name="web.xml" value="${webinf}/web.xml"/> <property name="classes" value="${webinf}/classes"/> <property name="lib" value="${top}/WEB-INF/lib"/> <property name="servlet.jar" value="$
{env.TOMCAT_HOME}/lib/servlet.jar"/>
<property name="deploy" value="${env.JBOSS_HOME}/deploy"/> <target name="clean">
code/Chapter3/SimpleTag/build.xml
<delete dir="${build}"/> <delete dir="${dist}"/> <delete dir="${war_dir}"/> </target> <target name="init"><!-- Create the build directory structure used by compile and dist -->
<mkdir dir="${build}"/> <mkdir dir="${dist}"/> <mkdir dir="${war_dir}"/> </target>
<target name="compile" depends="init">
<!-- Compile the java code from ${src} into ${build} --> <javac
srcdir="${top}/${src}" destdir="${build}"
classpath="${servlet.jar}"/> </target>
<target name="dist" depends="compile"> <!-- Put everything in a war file -->
<war warfile="${war_file}" webxml="${web.xml}"> <!-- include all JSPs in root level -->
<fileset dir="${top}/${src}"> <include name="*.jsp"/> </fileset>
<!-- include all tag libraries in WEB-INF,
but not web.xml (that's handled separately) --> <webinf dir="${webinf}">
<include name="*.tld"/> </webinf>
<!-- include all compiled classes --> <classes dir="${build}"/>
</war> </target>
<target name="deploy">
<!-- Copy the war file to the JBoss deploy directory --> <copy file="${war_file}" todir="${deploy}"/>
</target>
<target name="all" depends="clean,dist,deploy"/> </project>
7. Do not manually compile the Java files. Instead, use Ant to compile. Start at the
root SimpleTag directory and call Ant with the compile argument. You should
see output like this:
c:\j2ee\code\Chapter3\SimpleTag> ant compile Buildfile: build.xml
init:
[mkdir] Created dir: C:\j2ee\code\Chapter3\SimpleTag\build [mkdir] Created dir: C:\j2ee\code\Chapter3\SimpleTag\dist [mkdir] Created dir: C:\j2ee\code\Chapter3\SimpleTag\dist\lib compile:
[javac] Compiling 1 source file to C:\j2ee\code\Chapter3\SimpleTag\build BUILD SUCCESSFUL
Total time: 2 seconds
8. Do not manually create the .war distribution file. Instead, use Ant to create it.
c:\j2ee\code\Chapter3\SimpleTag> ant dist Buildfile: build.xml
init: dist:
[war] Building war:
C:\j2ee\code\Chapter3\SimpleTag\dist\lib\SimpleTag.war BUILD SUCCESSFUL
Total time: 2 seconds
9. Do not manually copy the .war file into your JBoss deploy directory. Instead, use
Ant to deploy it.
c:\j2ee\code\Chapter3\SimpleTag> ant deploy Buildfile: build.xml
deploy:
[copy] Copying 1 file to C:\j2ee\jboss\deploy BUILD SUCCESSFUL
Total time: 0 seconds
10. Test the application at http://localhost:8080/SimpleTag/tagExample.jsp
Why Ant rocks
It doesn't look like Ant is much better than doing things manually, but's only because we
intentionally did each step we could see what it looked like. In fact, Ant can easily
combine steps, by specifying in the build.xml file that a particular step requires other
steps to be performed in succession:
<target name="all" depends="clean,dist,deploy"/>
And you execute it like this:
c:\j2ee\code\Chapter3\SimpleTag> ant all Buildfile: build.xml
clean:
[delete] Deleting directory C:\j2ee\code\Chapter3\SimpleTag\build [delete] Deleting directory C:\j2ee\code\Chapter3\SimpleTag\dist init:
[mkdir] Created dir: C:\j2ee\code\Chapter3\SimpleTag\build [mkdir] Created dir: C:\j2ee\code\Chapter3\SimpleTag\dist [mkdir] Created dir: C:\j2ee\code\Chapter3\SimpleTag\dist\lib compile:
[javac] Compiling 1 source file to C:\j2ee\code\Chapter3\SimpleTag\build dist:
[war] Building war:
C:\j2ee\code\Chapter3\SimpleTag\dist\lib\SimpleTag.war deploy:
[copy] Copying 1 file to C:\j2ee\jboss\deploy all:
BUILD SUCCESSFUL Total time: 2 seconds
Voila! A completely clean compile and deployment in one easy step!
Tag Attributes
Attributes must be declared in the tag library descriptor, set as a class wide variable in the
tag class with an accessor that uses the same name as declared in the tag library
descriptor, and if the attribute is required, given a value when the tag is initialized in the
JSP. If the tag in the tag library descriptor looked like this:
<tag>
<name>exampleTagName</name>
<tagclass>com.masslight.tags.ExampleTag</tagclass> <bodycontent>empty</bodycontent>
<info>This is an example tag to demonstrate how attributes work</info> <attribute> <name>attributeOne</name> <required>true</required> </attribute> <attribute> <name>attributeTwo</name> <required>false</required> </attribute> </tag>
then the class would need to include the following code:
public class ExampleTag extends TagSupport { int attributeOne = 0;
String attributeTwo = 0; ....
....
public void setAttributeOne(String tempAttributeOne) {
attributeOne = Integer.valueOf(tempAttributeOne).intValue(); }
public void setAttributeTwo(String tempAttributeTwo) { attributeTwo = tempAttributeTwo;
} .... ....
and the JSP might look something like this - remember that attributeTwo was not
required:
<%@ taglib uri="WEB-INF/lib/tagLibraryName.tld" prefix="example" %> <example:exampleTagName attributeOne="1"/>
AttributeTag: using attributes in tag libraries
Do this:
1. Create the directory structure. Create an AttributeTag directory, then WEB-INF,
classes, and the directory structure com/masslight/tagExampleClasses.code/Chapter3/AttributeTag
AttributeTag | +-- tagExample.jsp (*) | +-- build.xml (*) | +-- WEB-INF | +-- web.xml (*) | +-- tagExampleLib.tld (*) | +-- classes | +-- com | +-- masslight | +-- tagExampleClasses | +-- GreetingAttributeTag.java (*) (*) denotes a file2. Create the JSP in the AttributeTag directory.
code/Chapter3/AttributeTag/tagExample.jsp
<%@ page language="java" %>
code/Chapter3/AttributeTag/tagExample.jsp
<html> <body> <greeter:Greeting greeting="Hey" /> </body> </html>3. Create the web.xml file in WEB-INF
code/Chapter3/AttributeTag/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <taglib> <taglib-uri> </taglib-uri> <taglib-location> </taglib-location> </taglib> </web-app>
4. Create the Java file in WEB-INF/classes/com/masslight/tagExampleClasses/
code/Chapter3/AttributeTag/WEB-INF/classes/com/masslight/tagExampleClasses/GreetingAttributeTag.java
package com.masslight.tagExampleClasses; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*;public class GreetingAttributeTag extends javax.servlet.jsp.tagext.TagSupport { public String greeting = "Hello";
public int doStartTag() throws JspTagException { try {
pageContext.getOut().print(greeting); } catch (Exception ex) {
throw new JspTagException("IO problems"); }
code/Chapter3/AttributeTag/WEB-INF/classes/com/masslight/tagExampleClasses/GreetingAttributeTag.java
}
public void setGreeting(String newGreeting) { greeting = newGreeting;
} }
5. Create the tag library descriptor file in WEB-INF
code/Chapter3/AttributeTag/WEB-INF/tagExampleLib.tld
<?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-jsptaglib_1_1.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>utility</shortname> <info>
A simple tag library for the examples </info>
<tag>
<name>Greeting</name>
<tagclass>com.masslight.tagExampleClasses.GreetingAttributeTag</tagclass> <info>Print a greeting specified by the greeting attribute</info> <bodycontent>empty</bodycontent> <attribute> <name>greeting</name> <required>true</required> </attribute> </tag> </taglib>
6. Create the build.xml file in the root AttributeTag directory.
code/Chapter3/AttributeTag/build.xml
<project name="AttributeTag" default="dist" basedir="."> <!-- set global properties for this build -->
<property environment="env"/> <property name="top" value="."/> <property name="src" value="."/>
code/Chapter3/AttributeTag/build.xml
<property name="build" value="build"/> <property name="dist" value="dist"/>
<property name="war_dir" value="${dist}/lib"/>
<property name="war_file" value="${war_dir}/AttributeTag.war"/> <property name="webinf" value="${top}/WEB-INF"/>
<property name="web.xml" value="${webinf}/web.xml"/> <property name="classes" value="${webinf}/classes"/> <property name="lib" value="${top}/WEB-INF/lib"/> <property name="servlet.jar" value="$
{env.TOMCAT_HOME}/lib/servlet.jar"/>
<property name="deploy" value="${env.JBOSS_HOME}/deploy"/> <target name="clean">
<!-- Delete our the ${build} and ${dist} directory trees --> <delete dir="${build}"/>
<delete dir="${dist}"/> <delete dir="${war_dir}"/> </target>
<target name="init">
<!-- Create the build directory structure used by compile and dist -->
<mkdir dir="${build}"/> <mkdir dir="${dist}"/> <mkdir dir="${war_dir}"/> </target>
<target name="compile" depends="init">
<!-- Compile the java code from ${src} into ${build} --> <javac
srcdir="${top}/${src}" destdir="${build}"
classpath="${servlet.jar}"/> </target>
<target name="dist" depends="compile"> <!-- Put everything in a war file -->
<war warfile="${war_file}" webxml="${web.xml}"> <!-- include all JSPs in root level -->
<fileset dir="${top}/${src}"> <include name="*.jsp"/> </fileset>
<!-- include all tag libraries in WEB-INF,
but not web.xml (that's handled separately) --> <webinf dir="${webinf}">
<include name="*.tld"/> <exclude name="web.xml"/> </webinf>
<!-- include all compiled classes --> <classes dir="${build}"/>
code/Chapter3/AttributeTag/build.xml
</war> </target>
<target name="deploy">
<!-- Copy the war file to the JBoss deploy directory --> <copy file="${war_file}" todir="${deploy}"/>
</target>
<target name="all" depends="clean,dist,deploy"/> </project>
7.
ant all to compile, jar, and deploy. You should see output like this:C:\work\j2ee\code\Chapter3\AttributeTag> ant all Buildfile: build.xml
clean: init:
[mkdir] Created dir: C:\work\j2ee\code\Chapter3\AttributeTag\build [mkdir] Created dir: C:\work\j2ee\code\Chapter3\AttributeTag\dist [mkdir] Created dir:
C:\work\j2ee\code\Chapter3\AttributeTag\dist\lib compile:
[javac] Compiling 1 source file to
C:\work\j2ee\code\Chapter3\AttributeTag\build dist:
[war] Building war:
C:\work\j2ee\code\Chapter3\AttributeTag\dist\lib\AttributeTag.war deploy:
[copy] Copying 1 file to C:\j2ee\jboss\deploy all:
BUILD SUCCESSFUL Total time: 8 seconds
8. Go to http://localhost:8080/AttributeTag/tagExample.jsp to test your
application
It is important to note that pageContext, session, and application objects can be
accessed from a tag class. This means that attributes from any and all of the different
scopes can be used in a tag class.
Creating a complex tag class
the class should extend javax.servlet.jsp.tagext.BodyTagSupport
should override the method called public int doStartTag() throws
JspTagException {
can override the method public void doInitBody() throws
JspTagException {
needs the method public int doAfterBody() throws JspTagException {
should override the method called public int doEndTag() throws
JspTagException {
does not need to override the public void release() method
the bodycontent tag in the tag descriptor library should be JSP
The tag class that extends TagBody allows the developer to execute code before and after
the body of the tag. Instead of returning SKIP_BODY or EVAL_BODY_INCLUDE, the
doStartTag method returns SKIP_BODY or EVAL_BODY_TAG. The doAfterBody method
returns either the SKIP_BODY or the EVAL_BODY_TAG which allows the tag to loop through
the tag's body until some condition is met. The content of the tag's body can be accessed
by a call to getBodyContent() which returns a BodyContent object. The developer
needs to write the contents of the body to the output stream by making a call to the
writeOut() method of the BodyContent object. To write out the content of the body, onemust write out contents of the getPreviousOut() method. If the developer does not
make this call, then nothing from the body of the tag will be shown. The doInitBody
method returns void and is not such an important method as the doAfterBody method.
doInitBodyCalled when the JSP enters the body of the tag - returns nothing
doAfterBody
Called when the JSP leaves the body of the tag - returns SKIP_BODY or
EVAL_BODY_TAGDo this:
1. Create the directory structure. The root directory is named ComplexTag; the rest is
the same as the previous examples.
2. Create tagExample.jsp, RepeatHelloTag.java, web.xml,
tagExampleLib.tld, and build.xmlcode/Chapter3/ComplexTag
ComplexTag |
+-- tagExample.jsp (*) |
code/Chapter3/ComplexTag
+-- build.xml (*) | +-- WEB-INF | +-- web.xml (*) | +-- tagExampleLib.tld (*) | +-- classes | +-- com | +-- masslight | +-- tagExampleClasses | +-- RepeatHelloTag.java (*) (*) denotes a filecode/Chapter3/ComplexTag/tagExample.jsp
<%@ page language="java" %><%@ taglib uri="WEB-INF/tagExampleLib.tld" prefix="greeter" %> <html> <body> <greeter:RepeatHello> Hello Again<br> </greeter:RepeatHello> </body> </html>
code/Chapter3/ComplexTag/WEB-INF/classes/com/masslight/tagExampleClasses/RepeatHelloTag.java
package com.masslight.tagExampleClasses; import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.*; import java.io.*;public class RepeatHelloTag extends javax.servlet.jsp.tagext.BodyTagSupport { int count = 1;
int numberOfIterations = 3;
String greeting = new String("Hello <BR>"); public int doStartTag() throws JspTagException {
code/Chapter3/ComplexTag/WEB-INF/classes/com/masslight/tagExampleClasses/RepeatHelloTag.java
try {
pageContext.getOut().print(greeting); } catch (Exception ex) {
throw new JspTagException("IO problems"); }
return EVAL_BODY_TAG; }
public int doAfterBody() throws JspTagException { try { if (count < numberOfIterations) { count++; return EVAL_BODY_TAG; } else {
BodyContent bodyContent = getBodyContent(); bodyContent.writeOut(getPreviousOut()); return SKIP_BODY;
} }
catch (Exception e) {
throw (new JspTagException("error")); } } }
code/Chapter3/ComplexTag/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <taglib> <taglib-uri>/WEB-INF/tagExampleLib.tld</taglib-uri> <taglib-location>/WEB-INF/tagExampleLib.tld</taglib-location> </taglib> </web-app>
code/Chapter3/ComplexTag/WEB-INF/tagExampleLib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglibPUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd">