J2EE Web Component Developer
J2EE Web Component Developer
5 Servlet Exceptions
6 Session Management
10 Web Applications
11 Design Patterns
OUTLINE
Introduction
Certification Benefits
Certification Roadmap
Exam Information
Exam Preparation
Coding Style
Files
Comments
Breaking Lines
Specifications
Courses
Chapter Summary
Introduction
This chapter introduces you to the Sun Certified Web Component Developer for the
J2EE Platform Examination. It identifies the topics that the exam covers, discusses
how the exam is given, and provides you with tips and other information on how to
take the exam.
The technologies the certification covers are servlets and JavaServer Pages (JSP).
Servlets are classes that look like those you use in J2SE, except they extend special
purpose classes that enable them to respond to Web server requests. JSP pages
extend servlet technology with a simple HTML (or XML) syntax. You can also include
normal Java statements. The servlet container actually compiles JSP pages into a
servlet the first time it is requested.
Let's look at the official definitions for these. The specification says, "JavaServer
Pages is the Java 2 Platform, Enterprise Edition (J2EE) technology for building
applications for generating dynamic Web content, such as HTML, DHTML, XHTML and
XML. The JavaServer Pages technology enables the easy authoring of web pages that
create dynamic content with maximum power and flexibility." So, it is a Web page
with a mixture of HTML and Java. This mixture makes JSP useful for the following
primary reasons:
• Separation of roles
Sun publishes a specification for servlets, too. I have modified slightly Sun's
definition for a servlet as a Java technology-based Web component, managed by a
container that generates dynamic content. Containers, sometimes called servlet
engines, are Web server extensions that provide servlet functionality. Servlets
interact with Web clients via a request/response paradigm implemented by the
servlet container.
The servlet container is a part of a Web server or application server that provides the
network services over which requests and responses are sent, decodes MIME-based
requests, and formats MIME-based responses. A servlet container also contains and
manages servlets through their lifecycle. According to the specification, the primary
advantages of servlets are
• They are faster than CGI scripts because each CGI script produces an entirely
new process that takes time to execute while a servlet is only another thread.
• The API is standard and public, unlike some proprietary APIs, server-side
languages, and scripts. For example, Microsoft's excellent Active Server Pages
is a so-called proprietary API, which means it only works on Windows
(although there are third-party plug-ins that enable you to run it on other
platforms).
• They can access all the huge J2SE and J2EE APIs. This is not true of, say,
JavaScript. JavaScript can run on many servers, but normally has limited
access to the backend. Not so with JSP and servlets, which can take full
advantage of the full power of Java.
The advantages of JSP and servlets are many, as stated previously. However, how
can you convince a recruiter that he or she should hire you to take advantage of
them? Nothing is more convincing than real examples. While these are best, you can
also interest the recruiter with a certification. The next section explains why you
should get certified.
Exam Information
This section covers practical details about the exam itself. For example, it tells you
how much the exam costs and how many questions are on it. More links and
resources are provided at the end of the chapter, but Table 1.1 provides a crisp list of
exam details.
Category Description
Objectives suned.sun.com/US/certification/java/exam_objectives.html
SCWCD suned.sun.com/US/certification/java/java_web.html
Home
Prometric www.2test.com/
Testing
Table 1.1. Exam Details
Category Description
Center
Legal suned.sun.com/US/certification/register/policies.html
Exam type Multiple choice, short answer, and drag and drop
Questions 60
Difficulty Easy-----------------x-------Hard
Based upon Servlet containers must be built with J2SE 1.2+ and J2EE 1.2+
ePractice suned.sun.com/US/catalog/courses/WGS-PREX-J080B.html
Exam (pay).
tmn.sun.com/WLC/servlet/GuestLoginServlet?id=programmer
(free)
1.2 For each of the HTTP methods, GET, POST, and HEAD, identify triggers that might
cause a browser to use the method, and identify benefits or functionality of the
method.
1.3 For each of the following operations, identify the interface and method name that
should be used:
• Set an HTTP response header; set the content type of the response
1.4 Identify the interface and method to access values and resources and to set
object attributes within the following three Web scopes:
• Request
• Session
• Context
2.2 Match the name with a description of purpose or functionality for each of the
following deployment descriptor elements:
• Servlet instance
• Servlet name
• Servlet class
• Initialization parameters
3.2 Identify the WebApp deployment descriptor element name that declares the
following features:
4.2 Given a set of business logic exceptions, identify the following: The configuration
that the deployment descriptor uses to handle each exception; how to use a
RequestDispatcher to forward the request to an error page; specify the handling
declaratively in the deployment descriptor.
4.3 Identify the method used for the following: Write a message to the WebApp log;
write a message and an exception to the WebApp log.
5.3 Given that URL-rewriting must be used for session management, identify the
design requirement on session-related HTML pages.
• Authentication, authorization
• Data integrity
• Auditing
• Malicious code
6.2 Identify the deployment descriptor element names, and their structure, that
declare the following:
• A security constraint
• A Web resource
• The login configuration
• A security role
6.3 Given an authentication type: BASIC, DIGEST, FORM, and CLIENT-CERT, identify
the correct definition of its mechanism.
• Local variables
• Instance variables
• Class variables
• Request attributes
• Session attributes
• Context attributes
7.2 Identify correct statements about differences between the multi-threaded and
single-threaded servlet models.
7.3 Identify the interface used to declare that a servlet must use the single thread
model.
• Directive
• Declaration
• Scriptlet
• Expression
8.2 Given a type of JSP tag, identify correct statements about its purpose or use.
8.3 Given a JSP tag type, identify the equivalent XML-based tags.
8.4 Identify the page directive attribute, and its values, that:
• Page translation
• Load class
• Create instance
• Call jspInit
• Call _jspService
• Call jspDestroy
8.6 Match correct descriptions about purpose, function, or use with any of the
following implicit objects:
• request
• response
• out
• session
• config
• application
• page
• pageContext
• exception
• A conditional statement
• An iteration statement
10.2 Given JSP page attribute scopes: request, session, and application, identify the
equivalent servlet code.
11.3 Given a custom tag library, identify properly formatted custom tag usage in a
JSP page. Uses include:
12.2 Identify the tag library descriptor element names that declare the following:
12.3 Given a custom tag, identify the necessary value for the bodycontent TLD
element for any of the following tag types:
• Empty-tag
• Custom tag that surrounds content that is used only by the tag
handler
12.4 Given a tag event method (doStartTag, doAfterBody, and doEndTag), identify
the correct description of the methods trigger.
• doStartTag
• doAfterBody
• doEndTag
• PageConext.getOut
• doStartTag
• doAfterBody
• doEndTag
12.7 Identify the method in the custom tag handler that accesses:
12.8 Identify methods that return an outer tag handler from within an inner tag
handler.
Section 13—Design Patterns
13.1 Given a scenario description with a list of issues, select the design pattern
(Value Objects, MVC, Data Access Object, or Business Delegate) that would best
solve those issues.
13.2 Match design patterns with statements describing potential benefits that accrue
from the use of the pattern, for any of the following patterns:
• Value Objects
• MVC
• Business Delegate
The previous topics and exam objectives are specific, so they will guide you in
selecting what details to concentrate on while preparing for the exam. The chapters
of this book are organized according to these topics and objectives. While all the
objectives are addressed in the book, they have been reorganized to make the topics
easier to study, as shown in Table 1.2.
Certification exam question count and time limits have been known to change over
time, but Sun has been consistent. The current format gives you 90 minutes to
complete the 60-question exam.
The short-answer questions ask you to enter a word or line of text. Typically these
are class/method names or a code statement. There aren't many of these questions
(<10%). However, you have to type it exactly as expected because the testing
software simply compares your answer to an internal string; it isn't parsed, so a
typed answer with correct syntax is wrong if it isn't an exact string match. Also, be
careful in that the answers are case-sensitive. Sun won't try to trick you with an
answer that looks correct, but the case is wrong. However, case does matter on all
questions so be careful.
When you arrive at the testing center, you will sign in and show two forms of ID. One
must have a picture, but both must have signatures. Although I once arrived early
and was allowed to take an exam ahead of schedule, Prometric frowns on early or
late arrivals, so arrive at least 10 minutes before your scheduled time and expect the
administrator to allow you to sit for the exam exactly on schedule. You can't bring
any paper into or out of the testing area. They will provide you with paper and
pencil/pen, but you will leave that at the test center. Of course, you can't take any
electronic device (PDA, phone) into the testing area.
The test software presents only one exam question on the screen at a time. It allows
you to mark a question if you would rather return to it later. You can also move
backward and forward between the questions you've answered and those you have
yet to answer.
The testing software gives you all the instructions, so it's easy to get through the
test. At the conclusion of your test, you will click the "Had enough of this?" button
(it's not really marked "Had enough of this?"!). This will cause the software to grade
your test. Next, there will be a button on the screen to print the results. You can click
it twice, or just copy the printout the test administrator provides to you. One copy
will be stamped with an "Authorized Testing Center" seal. The testing center software
automatically notifies Sun of your test results. You walk out knowing how you did.
You can also go to the official test database Web site
(suned.sun.com/US/certification/my_certification/index.html) to verify your score.
Chapter Summary
This section introduced you to the Sun Certified Web Component Developer for the
J2EE Platform Examination. It identified the topics that the exam covers, discussed
how the exam is given, and provided you with tips and other information on how to
take the exam. You should now be able to go on to study the remaining chapters of
Part I.
2. Details of the Sun Certified Web Component Developer for the J2EE Platform
(http://suned.sun.com/US/certification/java/java_web.html).
12. Expert group JSR053, who wrote the JSP and servlet specifications under the
Java Community Process (jcp.org/jsr/detail/53.jsp).
No formal objectives are covered in this chapter. It serves as background material for
subsequent chapters.
OUTLINE
Introduction
JSP
Chapter Summary
Review Questions
Introduction
This chapter helps you to prepare for the exam by providing an overview of JSP and
servlet technologies. It does not directly address any of the objectives listed by Sun.
It is general in scope, leaving the technical details to subsequent chapters. To pass
the exam, you have to go deeper than just learning syntax. Memorizing without
hands-on practice won't work. There are times when it helps to study how Sun
designed its classes. Likewise, there are several places throughout the book where I
offer a snippet from Tomcat's (or another open source container's) implementation
and walk through its source code. You'll discover first-hand how a servlet container
works. This chapter also helps you understand the market forces that shaped Java in
general and servlets in particular. It also discusses where JSPs fit in the server-side
pantheon of scripting technologies. Why even have JSP, since servlets are the real
thing? The overview below will answer this question and others, answers that will
demystify important issues.
Glad for the new business, AT&T installed the first cross-country link between UCLA
and BBN. The world didn't know it at the time, but a vortex was born; something
other than people was causing busy signals. By 1973, hundreds of computers
between organizations, even across the ocean, were shoveling data to each other.
The WWW crawled into a crowd as Gopher, WAIS, telnet, email, and many other
services ruled the networks. All the activity and growth numbers were impressive,
but no one was ready for what came next. In 1993, Marc Andersen and pals wanted
to see what was on the Internet, so they developed a new computer program called
the NCSA Mosaic (National Center for Supercomputing Applications at the University
of Illinois) based on Berners-Lee's contraption. They gave it away!
Mosaic started a worldwide frenzy: The Internet exploded. Even the most optimistic
proponents were shocked. In less than a decade, the number of hosts snowballed to
nearly 200 million and the number of users approached one billion!
There is more news in the making. The Net is being invaded by a swarm of aliens
that will dwarf the human user count. With the advent of Internet capability in non-
PC devices including phones, GPS, PDAs, and even cars and refrigerators, the
Internet is about to mushroom again as devices using the Net multiply,
outnumbering people by several orders of magnitude.
Remarkably, the Internet is only a teenager. Our prodigy has no idea what it will do
when it grows up. So, let's help it decide. As you will see in the next chapters,
servlets and JSPs are tools we can use to direct all those bytes down the straight and
narrow path. It is at the juncture between users and repositories where the Internet
struggles most. If we could just close this distance, even a little, then our
contribution will be very valuable. Admittedly, Java has its disappointments (Gosling
and gang simply copied switch blocks from C without adding value such as allowing
strings), but servlets are mighty because they have access to the entire Java API.
Since JSPs metamorphose into servlets, the technology is very effective. It gives us
intelligent bricks to build a wall around embattled OS warlords, rendering all their
wares into one virtual platform.
Now that we have discussed the plumbing, our attention turns to the content. What
files should be published? Perhaps our data isn't in files, but in databases. Some of
the content is old, but the majority of data is only days old. This immediacy drives
traffic on the Internet.
With HTML running over HTTP, an end user can browse files housed on a distant
server. This is useful, but live data is even better. The Common Gateway Interface
(CGI) specification allowed a Web server to reach beyond the file server and grab
data from corporate databases. This also meant that CGI could change the HTML on-
the-fly. The CGI specification was a major breakthrough in Web application
development. The standard made sure that the same CGI program worked on
different Web servers.
CGI became the most common means of delivering dynamic content. Alas, the
pressure of the Internet was too much. CGI's performance just couldn't keep up
because of a technical glitch where each request for a CGI script spawned a separate
process. This design nibbled server resources off-hours but devoured them during
peak loads. Further demand came, but, fortunately, better solutions came also.
Functionality and scalability became key. Plain file-returning Web servers, even CGI-
enabled ones, needed to mature into true application servers.
Java has come a long way since its inception in 1991 when Sun launched "Project
Green," which tried to integrate digitally controlled consumer devices like TV sets, CD
players, and computers. OAK (a name which comes from an oak tree outside
Gosling's window!) was born, but didn't come to life until HotJava and applets. This
was a humble beginning. Sun threw the gauntlet down in 1995 by releasing Java as
open source. The feedback was tremendous, and fixed more than just a few bugs.
This drove Java deep into the server-side development industry.
Naturally, Sun packed Java with Internet functionality, and in June 1997 Sun
announced the servlet interface. Servlets targeted CGI. Unlike CGI, which starts a
process for each request, Servlets run in a single process using finer grain threads
instead. Servlets represent a more efficient architecture, helping them withstand the
Internet's mercurial crush. How can we possibly keep up? It's hard, but we can do it
with Java servlets, which provide the foundation for developing Java Web
components. One advantage to servlets is that the additional overhead for each
additional simultaneous request the servlet handles is very small.
Servlets require real Java programming skills. However, the look and feel belongs to
the marketing team. So, what can the graphics people do? They can thank Sun for
JavaServer Pages (JSP), which was released in 1998. Inspired, some say copied, by
the immensely successful Microsoft ASP, Sun made it easy to write dynamic HTML
pages. With JSP, the marketing team can do their work, and with servlets the
engineers can do theirs. Together, servlets and JSPs pages enable you to develop
modular, maintainable, scalable, and portable Web applications. Another advantage is
how Java provides a separation between JSPs, which are created by the marketers,
and the JavaBeans they use, which are created by the engineers.
The servlet container is an extension of a Web server in the same way CGI, ASP, and
PHP are. A servlet functions like these, but the language is Java. The servlet doesn't
talk to the client directly. The Web server does that. In a chain of processes, the
client sends a request to the Web server, which hands it to the container, which
hands it to the servlet (which sometimes hands it off yet again to a database or a
JavaBean). The response retraces the course from the servlet to the container to the
Web server to the client. Of course there are several other steps that happen too
(JSP may need to be converted to servlet, and the TCP/IP packet hops from node to
node). A snapshot of these steps is: Web server-> container-> servlet-> JavaBean->
DB.
The servlet architecture makes the container manage servlets through their lifecycle.
The container invokes a servlet upon an HTTP request, providing that servlet with
request information (stored in a request object) and the container configuration. The
servlet goes about its deed. When finished, it hands back HTML and objects that hold
information about the response. The container then forms an HTTP response and
returns it to the client (see Figure 3.1).
The container itself is often written in Java, since the specification defines it as
operating inside a JVM. Not surprisingly, vendors vary in their implementation,
including writing their containers in other languages (C++ is popular) mimicking a
Java environment. They argue the application server is faster that way.
Listing 3.1 is a template for your servlets. It won't compile as-is, but shows the main
outline to get you started.
//import statements
// Instance Variables
// Static Initializer
/**
* Initialize this servlet. Called only once in lifetime
*/
public void init() throws ServletException
{
// handle initialization chores
}
/**
* This gets called with every request.
* It is called first. The parent class already has
* this method so you don't have to override it,
* but you can.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if input/output error occurs
* @exception ServletException if a servlet-specified
* error occurs
*/
protected void service(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
//bypass doGet and doPost by handling request here.
// perhaps:
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
StringBuffer html = new StringBuffer();
html.append("<html>\n");
html.append("<head><title>Servlet Example</title>" +
"</head>\n");
html.append("<body>\n");
html.append("Servlet Example");
html.append("</body>");
html.append("</html>");
out.print( html.toString() );
//you out.println() or use buffer as above.
}
/*The service method will process the request so the doGet
and doPost methods are never called in this class. They
are included to show you what they look like. You could
remove the service method (the one here actually
overrides the default one in the super class) and then
the doGet and doPost methods will get called.
*/
/**
* Process a GET request for the specified resource.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if input/output error occurs
* @exception ServletException if a servlet-specified
* error occurs
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
// Serve the requested resource,
// including the data content.
}
/**
* Process a POST request for the specified resource.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if input/output error occurs
* @exception ServletException if a servlet-specified
* error occurs
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
//often just throw it at doGet()
doGet(request, response);
}
/**
* Process a PUT request for the specified resource.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
*
* @exception IOException if input/output error occurs
* @exception ServletException if a servlet-specified
* error occurs
*/
protected void doPut(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException
{
//rarely used
}
/**
* A few more convenience methods
*/
/**
* last thing called in a servlet, a funeral method
*/
public void destroy()
{
// clean up what init starts like DB connection
}
}
The template is a useful blueprint for your servlet, but they can be as short as the
program in Listing 3.2:
The servlet interface is the central abstraction of the servlet API. All servlets
implement this interface. Usually, a servlet extends the HttpServlet class that
implements the interface. In addition, the servlet container creates the
ServletContext object, through which a servlet can log events, set and store
attributes at the application level (across browsers) or session level (across pages,
but same browser), and grab file paths.
JSP
JSPs are converted to servlets before the container runs them. This is a nice trick by
Sun because non-programmers can create JSP pages. Although JSP reduces the
required skill level, JSP becomes a servlet, with the nice performance and portability
benefits. Let's walk through the JSP-to-servlet process.
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
static {
}
public jsp_0005fservlet$jsp( ) {
}
if (_jspx_inited == false) {
synchronized (this) {
if (_jspx_inited == false) {
_jspx_init();
_jspx_inited = true;
}
}
}
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=" +
"ISO-8859-1");
pageContext = _jspxFactory.getPageContext(this,
request, response, "",
true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// end
} catch (Throwable t) {
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (pageContext != null)
pageContext.handlePageException(t);
} finally {
if (_jspxFactory != null)
jspxFactory.releasePageContext(pageContext);
}
}
}
// servlet code generated from JSP source may vary
//from container to container
As you can see, Tomcat does a lot of work when it converts a JSP to a servlet. If you
look at the source that is sent to your browser, you will see the original HTML in the
JSP file. The plain HTML in a JSP is always passed through. What happens when we
throw in a little Java syntax? I revised the JSP so that it contains two lines of Java
code, as shown in Listing 3.5.
if (_jspx_inited == false) {
synchronized (this) {
if (_jspx_inited == false) {
_jspx_init();
_jspx_inited = true;
}
}
}
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=ISO-8859-1");
pageContext = _jspxFactory.getPageContext(this,
request, response,
"", true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// HTML // begin [file="/jsp/jsp_servlet.jsp"...]
out.write("<!--\r\n Simple demonstration of how" +
" Tomcat converts\r\n JSP to a servlet.\r\n-->" +
"\r\n<html>\r\n<body>\r\n" +
"Devyn likes <b>R/C Buggies</b>. <br>\r\n");
// end
// HTML // begin [file="/jsp/jsp_servlet.jsp";from=...]
out.write("\r\n ");
// end
// begin [file="/jsp/jsp_servlet.jsp";from=...]
out.print(count * factor);
// end
// HTML // begin [file="/jsp/jsp_servlet.jsp";from=...]
out.write("\r\n\r\n</body>\r\n</html>\r\n");
// end
}
You can see how Tomcat takes the top level count and factor variables declared at
the top of the JSP and generates the declarations as class-level variables in the
servlet. So, <%=count * factor%> becomes out.print(count * factor);.
Once the translation is completed, the servlet is compiled and loaded into memory.
Every subsequent request for this JSP will trigger Tomcat to compare the
modification date of the loaded servlet with the date of the JSP. If the JSP changes,
Tomcat will translate and recompile it.
Chapter Summary
In this chapter, you reviewed the history that led to servlet and JSP architecture. You
learned, in broad terms, how servlet containers work. The following review and exam
questions will test your knowledge of these topics and will help you to determine
whether your knowledge of the API is sufficient to answer the questions you'll
encounter in the certification exam.
KEY TERMS
• Servlet container
• Web application
• Thread safety
A1: Servlets are written in the Java language. JSPs on the other hand use a
combination of HTML and Java. Eventually JSPs are converted into a pure Java
servlet. See "Servlet and JSP History," earlier in this chapter.
2:What is the servlet life cycle and what manages it?
A2: The servlet life cycle refers to the loading, initialization, invoking, and killing of a
servlet. The container manages this life cycle. See "Web Servers and Servlet
Containers," earlier in this chapter.
3:What protocol do servlets and JSP use to communicate with clients?
A3: Servlets use the HTTP protocol. See "Web Servers and Servlet Containers," earlier
in this chapter.
4:What is the relationship between servlets and JSP?
A4: JSPs are converted to servlets. First, the JSP source is parsed and a Java source
file is generated. Then this source is compiled into a servlet. See "JSP," earlier in
this chapter.
2. Exam objectives for the Sun Certified Web Component Developer for J2EE
Platform, http://suned.sun.com/US/certification/java/exam_objectives.html.
This chapter covers the following objectives listed by Sun in "Section 1—The Servlet
Model" and "Section 3—The Servlet Container Model."
1.1 For each of the HTTP methods, GET, POST, and PUT, identify the
corresponding method in the HttpServlet class.
• The HTTP methods GET, POST, and PUT are how browsers and Web servers
communicate the purpose of communication. A GET simply wants to retrieve a
page without providing much information. A POST, however, can package lots
of form or file information with its request. A PUT is for uploading a file. The
HttpServlet class has a corresponding method for each HTTP method,
including doGet(), doPost(), and doPut().
1.2 For each of the HTTP methods, GET, POST, and HEAD, identify triggers that
might cause a browser to use the method, and identify benefits or
functionality of the method.
• This objective asks you to understand the events associated with each type of
request. For example, clicking a hyperlink will send a GET request to a Web
server, but clicking a Submit button (when the action is set to "post") will
send a POST request.
1.3 For each of the following operations, identify the interface and method
name that should be used to
1.4 Identify the interface and method to access values and resources and to
set object attributes within the following three Web scopes:
• Request
• Session
• Context
• This objective addresses the idea of scope. When something has Context
scope, it is application-wide and all users can share data. Session scope
means one user can share data across page views, but other users can't.
Request scope restricts data to only that page.
1.5 Given a life-cycle method, identify correct statements about its purpose
or about how and when it is invoked. These methods are
• init
• service
• destroy
• The container manages the servlet life-cycle. This part of the chapter
explains, with examples, how the container initializes a servlet with a call to
the init() method. Then it calls the service() method upon every request.
Finally, when the servlet is about to be removed from memory, the container
calls its destroy() method. This gives the servlet one last chance to clean up
resources.
3.1 Identify the uses for and the interfaces (or classes) and methods to
achieve the following features:
• These elements let you get and monitor servlet attributes. Not only can you
get them and change them too, but you can actually put in place behavior to
occur when an attribute changes. The listeners are event-driven triggers.
When an attribute changes, special targeted methods are called. In them, you
can define special actions, such as adding a note to the log every time the
user count changes (perhaps a context attribute called counter).
• As explained in the previous objective, these elements let you get and
monitor Servlet attributes. There is a difference here in that Sun wants you to
understand how this works in a distributable Web application.
OUTLINE
Introduction
GET
POST
PUT
GET
POST
HEAD
Form Parameters
Request
Session
Context
Servlet Life-cycle
Using a RequestDispatcher
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• The key to this section of the exam is understanding how servlets implement
the Servlet interface, which defines life-cycle methods. The Servlet Container
(such as Apache Tomcat) is itself an application that monitors a port on a
given IP address. Servlets generate responses to HTTP requests. To do so, the
container loads your servlet (if it isn't in memory already) and calls the
methods defined in the interface. This is the foundation of servlet and JSP
architecture.
• There are many methods to know. It is easier if you learn the methods in
groups according to theme. For example, write a servlet that has HttpServlet
methods which handle all three GET, POST, and PUT types of request.
• Each JavaServer Page is transformed into a servlet that is compiled and then
loaded. Therefore much of what you learn here applies to the JSP section of
the exam too.
Introduction
JSP and servlets have greatly enhanced the way in which you can create and manage
Web pages. The difficulty level of coding JSP is between that of coding HTML and
pure Java. Servlets are pure Java. The idea behind having both is providing a way for
non-programmers to contribute functionality through JSP. You can "program" a JSP
page almost as easily as you can write an HTML page. For simple tasks like
displaying the current date, you write a normal HTML page and add only a small
amount of Java as a scriptlet. For big tasks like processing a shopping cart, you use
JSP as the mediator between the Web form and a component(s) (bean or servlet)
that has all the horsepower. Most of the code in a Web application will go into
servlets. The JSP portion is a soft front end to the application that, typically,
marketing can use comfortably.
There is a lot that happens when a servlet is invoked. This chapter covers much
material that explains each step of the process. At this point, it will help to provide
an overview of what happens in a typical JSP/servlet request. The sequence of
events starts with a browser sending a request to a Web server. The server hands
the request to a Servlet Container. The container loads the servlet (if it isn't already
loaded), instantiates a request and response objects, and then hands these objects
to the servlet by calling first its init() method, then its service() method, and
lastly the destroy() method. The service() method will typically call one of the
doXXX() methods such as doGet().
All these steps are covered in detail later in this chapter. Presently, just review the
overall process presented in Figure 4.1.
Let's study an example of a servlet. The following is a fully functioning, albeit trivial,
servlet example. Listing 4.1 represents all that is required to have a complete
servlet.
Listing 4.1 The Source Code of a Minimum Servlet
/* SimpleServletExample.java, v 1.0
*
*/
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* A simple servlet.
* SCWCD Exam Objective 1.1 = doGet(), doPost(), doPut()
*
* @author Reader@Que
*/
out.println("<html>");
out.println("<head>");
out.println("<title> A simple servlet. </title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Simple Servlet</h1>");
out.println("This is a trivial " +
"example of a servlet.");
out.println("</body>");
out.println("</html>");
}
}
Listing 4.1 showed you an example of a servlet. The code is ordinary, but notice one
small thing about printing to the browser. This example uses PrintWriter instead of
using ServletOutputStream. The former is used for text, while the latter is used for
bytes. See Figure 4.2 for a picture of the output. Listing 4.2 is the HTML the servlet
generates and sends to the browser.
The HTML in Listing 4.2 is rendered by a browser so that it looks like Figure 4.2.
IN THE FIELD: HOW DOES A SERVLET WORK?
You write a servlet and compile it, and then place it in the appropriate
directory. When the Servlet Container starts, it will preload your servlet in
memory if specified in the web.xml configuration file. If your servlet is not
already loaded (not listed in the web.xml configuration file), its instance will
be created as soon as a request for it is received by the Servlet Container.
The first time it is loaded, the container calls your servlet's init() method, if
there is one. Notice that it gets called only once, so place one-off
functionality in this method (such as database connection, file object). Now
that your servlet is ready, it waits for requests. The container will call your
service() method each time a request is received for your servlet. The
HttpServlet class (which your servlet must extend) already has this
method, so you don't have to write one, but you can override it. The
service() method then passes the request on to the appropriate method
(usually GET for simple requests and POST to submit data, say a Web page
form) such as the doGet() method if it is a GET request, or the doPost()
method if it is a POST request. The doXXX() methods are the ones you need
to override and where you will spend most of your effort. The servlet
processes the request (code you write in doGet()), returning a response to
the container. The container sends the text of the response back to the
browser.
The preceding JSP and servlet examples are part of a Web application. A Web
application is a collection of servlets, JSP pages, HTML documents, and other
Web resources (such as image files, compressed archives, and other data).
This collection may be packaged into an archive or exist as separate files in
an open directory structure. Since you have many servlet classes, JSP pages,
HTML pages, and other supporting libraries and files for a given Web
application, there are many dependencies. These are not trivial to manage. It
is vital that all parts go in their correct locations in the Web application
archive or in an open directory structure. Once you get the dependencies
resolved, it is a good idea to package the collection into a Web application
archive, a single file with the .war extension that contains all of the
components of a Web application. You can do this using standard JAR tools.
• GET
• POST
• PUT
This exam objective addresses the most-used feature of servlets, namely, responding
to HTTP requests. The exam will have several questions on this topic. These three
types of requests dominate browser-server traffic.
The following code is a minimal template showing you how to use the GET, POST, and
PUT methods. GET appends data to the URL before the URL is submitted to the
server, whereas POST sends the data to the server separately from the URL. GET
submissions can only be 1KB in length in most cases, whereas POST submissions can
be arbitrarily large. The results of a GET submission can be reliably bookmarked,
whereas the results of a POST submission can't. There are several differences
between them which are explained later in this section.
These methods are called by the service method (not required in your servlet as it is
in HttpServlet, as this method is inherited from HttpServlet). Together they can look
like Listing 4.3.
Listing 4.4 Servlet That Handles GET, POST, and PUT Requests
/* doGetdoPostdoPutServlet.java, v 1.0
* SCWCD Exam Objective 1.1 = doGet(), doPost(), doPut()
*
*/
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* A servlet that reports back to the browser
* the type of request received.
*
* @author Reader@Que
*/
out.println("<html>");
out.println("<head>");
out.println("<title>doGetdoPostdoPutServlet" +
"</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Your Request</h1>");
out.println("Your request type: " + requestType);
out.println("</body>");
out.println("</html>");
}
}
Listing 4.3 sends a basic HTML message back to the browser that looks like Figure
4.3.
if (method.equals(METHOD_GET))
{
doGet(req, resp);
} else if (method.equals(METHOD_POST))
{
doPost(req, resp);
} else if (method.equals(METHOD_PUT))
{
doPut(req, resp);
} else
{
// Servlet doesn't currently support
// other types of request.
String errMsg = "Method Not Supported");
resp.sendError(
HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
GET
The GET type request is normally used for simple HTML page requests. It has this
syntax:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{ //your code here}
When you write a servlet, this is the one method that you will start with. If this
method is all you had in your servlet, it would handle the majority of your Web
server's needs regarding this servlet.
Notice, that the init() and service() methods involved in a request are already
provided by the HttpServlet class, so they don't need to be overridden, although
you can do so.
The GET is the most common type of browser request. According to the Hypertext
Transfer Protocol standard, the GET method means "retrieve whatever information (in
the form of an entity) is identified by the Request-URI." For a full discussion on
naming and addressing (URL vs. URI) please see http://www.w3.org/Addressing/. If
the Request-URI refers to a data-producing process, it is the produced data which
shall be returned as the entity in the response and not the source text of the
process, unless that text happens to be the output of the process." In our example,
the test message is the entity.
This method is where your servlet does most of its labor. You could process a simple
HTML response or hit a database with a query.
Table 4.1 provides a list of differences between GET and POST requests.
GET
Query string or form data is simply appended to the URL as name-value pairs.
http://mycompany.com/support?Name=John+Smith&Product=go+kart&Complaint=the+engine+is+sp
doGet().
GET
ASCII.
Easy to bookmark.
Used more.
The following short listings exemplify the GET and POST requests
<html>
<body>
<form method="GET" action="/myservlet/process">
<input type="text" name="product" size="25"
maxlength="35" value="type product name here">
<input type="submit" name="submitButton" value="Submit">
</form>
</body>
</html>
<html>
<body>
<form method="post" action="/myservlet/process">
<input type="text" name="product" size="25"
maxlength="35" value="type product name here">
<input type="submit" name="submitButton" value="Submit">
</form>
</body>
</html>
POST
The POST type request is most often used by HTML forms. It has this syntax:
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{ //your code here}
The POST method is more sophisticated than a GET request. Normally, a Web form
has fields whose names and values are sent to the server in key-value pairs. The
POST is designed for posting long messages (for example, to a bulletin board,
newsgroup, mailing list); providing a block of data, such as the result of submitting a
form; and submitting long data fields to a database (such as a SQL insert of lengthy
string). Sometimes the action performed by the POST method doesn't return a
standard HTML page. Suppose you updated a database table. The database doesn't
send back an HTML confirmation on its own. You would have to wrap the database
results in HTML manually. You also have the option of sending back an empty
response with a header status of either 200 (OK) or 204 (No Content). A No Content
status tells the browser that it shouldn't expect any HTML. You might want to do this
if it is software to software interaction and no eyeballs are waiting to see a Web
page.
Normally, this method is used to process a form submitted by a browser. You will
very likely be looking for form field names and values. For example, the following
snippet is how you would grab the value of the field formCountField that the user
supplied a value for:
//read the query string
int customerRequest = 0;
String count = request.getParameter("formCountField");
try
{
customerRequest = Integer.parseInt(count);
} catch (Exception e)
{ // NumberFormat or NullPointerException
processError(e);
}
PUT
The PUT type request is a means of uploading files to the server. While uploading is
its original intent, I have not seen it used much. Instead, POST is generally used to
upload files. The PUT handler has this syntax:
public void doPut(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{ //your code here}
The doPut() method is called by the server (via the service method) to handle a PUT
request. Uploading files from a browser has always been difficult. The idea behind
the PUT operation is to make uploading straightforward. It is supposed to allow a
client to place a file on the server, just like sending a file by FTP. The javadoc for this
method warns that when overriding this method, you should leave intact any content
headers sent with the request (including Content-Length, Content-Type, Content-
Transfer-Encoding, Content-Encoding, Content-Base, Content-Language, Content-
Location, Content-MD5, and Content-Range). This method is rarely used, but it is
powerful if you need it.
Listing 4.5 is a simplified HTML page that creates a file upload page that will direct
the file contents to a servlet.
Listing 4.6 Servlet That Handles a File Upload from the Client
import java.io.*;
import java.util.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
try
{
int i;
InputStream input;
input = req.getInputStream();
BufferedInputStream in =
new BufferedInputStream(input);
BufferedReader reader =
new BufferedReader(
new InputStreamReader(in));
File outputFile =
new File("c:/temp/out.txt");
FileWriter out =
new FileWriter(outputFile);
out.close();
in.close();
}
catch (IOException e) {}
}
}
You need to account for the header and footer lines that the stream attaches to the
actual file contents. The stream looks like this:
------------BB1rHqKAOHkiUoiFS3VI6v
Content-Disposition: form-data; name="FileToUpload";
filename="Candle.txt"
Content-Type: application/octet-stream; name="Candle. txt"
// ...
//actual file content here
// ...
------------BB1rHqKAOHkiUoiFS3VI6v
Content-Disposition: form-data; name="UploadFile"
Upload
------------BB1rHqKAOHkiUoiFS3VI6v
Therefore, you will need to search (indexOf) for the start of the actual file content
by looking for the Content-Type and subsequent name parameters like so:
int headerEnd = line.indexOf("Content-Type: ");
headerEnd = line.indexOf("name=\"", headerEnd);
headerEnd = line.indexOf("\"", headerEnd + 7); //last quote
Likewise, you need to search the end of the file for the telltale Content-Disposition
and preceding "------------" marker like so:
int footerStart =
line.lastIndexOf ("Content- Disposition: ");
footerStart = line.lastIndexOf ("---------", footerStart);
Lastly, you will grab the text between the two like so:
fileContent = line.substring(headerEnd, footerStart);
You can refer to RFC 1867 to learn more about uploading files through an HTML form
(www.servlets.com/rfcs/rfc1867.html). This is all tedious, so you might just grab an
open source (http://www.servlets.com/cos/index.html) or commercial Bean that
uploads files such as uploadBean
(www.javazoom.net/jzservlets/uploadbean/uploadbean.html) or jspSmartUpload
(www.jspsmart.com/).
Listing 4.6 worked when placed in the doPost() method (and the form method of
Listing 4.5 is set to post), but did not work in the doPut() method using IE or Opera
against Tomcat (version 4). I verified that the doPut() method is called as expected
in the servlet. However, even after much tweaking, this file upload code failed when
placed in the doPut method as shown previously. If you only change doPut to doPost
it works?! Although I need to research this problem with Tomcat, you do need to
understand that PUT is used to upload files to a Web server and that this is usually
done by non-browser, client-side Web content development tools.
Triggering HttpServlet GET, POST, and PUT Methods
1.2 For each of the HTTP methods, GET, POST, and HEAD, identify triggers that
might cause a browser to use the method, and identify benefits or
functionality of the method.
• GET
• POST
• HEAD
This exam objective focuses on what triggers the events or methods in your servlets.
For example, what action can a client take that results in the doGet() method being
called in your servlet?
GET
As noted previously, the GET type request is normally used for simple HTML page
requests. The types of events that generate this type of request are clicking on a
hyperlink, changing the address directly by typing in the address textbox on a
browser or application that has HTML functionality, and submitting an HTML form
where the method header is set to get as in method=get. Also, a GET request is
triggered when selecting a favorite from the Favorites list and using JavaScript to
change location.href. Usually the browser is configured to send a GET request
even if no method is set explicitly by the HTML.
• It allows bookmarks.
POST
This occurs when a browser or application submits an HTML form with the method
attribute set to post as in method=post.
• It sends information to the server such as form fields, large text bodies, and
key-value pairs.
• It hides form data because it isn't passed as a query string, but in the
message body.
• It disallows bookmarks.
HEAD
A browser or application will sometimes send a request to a server just to check the
status or get information (for example, "can you handle file upload?") from the
server.
The HEAD method returns the same header lines that a GET method would return;
however, no body or content is returned. This is often accomplished by calling
doGet(), setting the headers but not setting any output, and then returning the
response (without any body) to the requester.
The primary benefit of this method is message size. The HEAD method receives and
returns very small messages. Therefore it is fast and lightweight on both ends.
1.3 For each of the following operations, identify the interface and method
name that should be used to
Form Parameters
The interface that defines the form parameter methods is ServletRequest. This
interface is implemented by the Web container to get the parameters from a request.
Parameters are sent in the query string or posted form data. The four methods
associated with getting parameters are
• getParameter(String). You use this method if you know the particular
parameter name. It returns the value of a request parameter as a string, or
null if the parameter does not exist. Use this method when you are sure the
parameter has only one value; otherwise use getParameterValues(). Be
careful: If you use this method with a multivalued parameter, you won't get
an error. You will get the first value in the array returned by
getParameterValues().
Listing 4.7, the following code snippet, demonstrates how you would grab the
parameters from a request.
while (parameterNames.hasMoreElements()) {
String name =
(String)parameterNames.nextElement();
String value = request.getParameter(name);
out.println(name + " = " + value + "<br/>");
}
}
}
Retrieving a Servlet Initialization Parameter
A Web application includes many parts; it rarely is just one class or file. It can be a
combination of JSP pages, servlets, tag libraries, Java beans, and other class files.
The Java Virtual Machine creates a memory box for all of these called a
ServletContext object which maintains information (context) about your Web
application. You access the ServletContext for information about the application
state. As the API states, the ServletContext allows you access many types of
information. You can get application-level initialization parameters. You can also set
and get application attributes, as well as the major and minor version of the Servlet
API that this Servlet Container supports. One very interesting capability is to get hold
of RequestDispatcher object to forward requests to other application components
within the server, or to include responses from certain components within the servlet
and to log a message to application log file. The ServletContext object is how you
can set, get, and change application (not session) level attributes and talk to the
Servlet Container.
Some parameters have no information, so this method will return a string containing
at least the Servlet Container name and version number. The
getInitParameterNames method retrieves the names of the servlet's initialization
parameters as an Enumeration of string objects. If there aren't any, it returns an
empty Enumeration. Be careful; don't confuse this with session-wide attributes.
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
/**
* Displaying request headers
*
* @author Reader@Que
*/
Sending a binary stream to the client is not easy. Listing 4.10 will help you do it
right.
/**Clean up resources*/
public void destroy()
{
//If you need to clean up resources.
//Otherwise don't override.
}
String getContentType(String fileName)
{
String extension[] =
{ // File Extensions
"txt", //0 - plain text
"htm", //1 - hypertext
"jpg", //2 - JPEG image
"gif", //3 - gif image
"pdf", //4 - adobe pdf
"doc", //5 - Microsoft Word
}, // you can add more
mimeType[] =
{ // mime types
"text/plain", //0 - plain text
"text/html", //1 - hypertext
"image/jpg", //2 - image
"image/gif", //3 - image
"application/pdf", //4 - Adobe pdf
"application/msword", //5 - Microsoft Word
}, // you can add more
contentType = "text/html"; // default type
return contentType;
}
}
The two potential problems with this method are sending a bad URL to the client and
using this method after the response has already been committed. The bad URL will
look bad, but not produce an error. The latter, though, will throw an
IllegalStateException. Furthermore, after using this method, the response is
committed and can't be written to, or you'll get an error. One nice feature is that this
method writes a short response body including a hyperlink to the new location. This
way, if the browser doesn't support redirects, it will still get the new link. Use the
following syntax for this method:
// Suppose this portion of the server is down.
// Redirect the user to an explanation page.
redirectPath = "./error/notAvailable.html";
response.sendRedirect(redirectPath);
1.4 Identify the interface and method to access values and resources and to
set object attributes within the following three Web scopes:
• Request
• Session
• Context
This objective requires you to understand how to set and get name-value attributes
at three different levels. The breadth of scope increases from Request to Session to
Context, the widest scope.
Table 4.2 provides a definition of the three object scopes of concern under this
objective, namely, Request, Session, and Application.
Table 4.2. Request, Session, and Application Scope
application All request to same Web Life of container or explicitly killed (such
application as container administration action).
The idea here is if you set an attribute (that is, request.setAttribute()), when can
you access it? The answer depends on which object was used to the attribute. So, if
you set an attribute with the request object, then the scope of that specific attribute
is only Request. You can't access it once the request is complete. You can't see this
attribute in another request even if it is in the same session. Conversely, any
attribute set with the ServletContext object can be seen in all sessions and all
requests.
Listing 4.11 is a program that demonstrates how you could use access attributes
from the three primary scopes of Request, Session, and Application. You can also use
setAttribute() for each of these scopes.
out.println("<html>");
out.println(" <head>");
out.println(" <title>Attribute Scope Example" + "</title>");
out.println(" </head>");
out.println(" <body>");
out.println(" <p align=center>");
out.println(" <h2>Attribute Scope Example</h2>");
String url=request.getScheme()+"://"+
request.getServerName()+":"+
request.getServerPort()+
request.getRequestURI();
out.println(" </td>");
out.println(" </tr>");
out.println(" </table>");
out.println(" </p>");
out.println(" <br>");
printHeader(out,"Context attributes:");
enum = context.getAttributeNames();
while (enum.hasMoreElements()) {
String key = (String)enum.nextElement();
Object val = context.getAttribute(key);
printValue(out,key,val.toString());
}
printVoid(out);
printHeader(out,"Request attributes:");
enum = request.getAttributeNames();
while (enum.hasMoreElements()) {
String key = (String)enum.nextElement();
Object val = request.getAttribute(key);
printValue(out,key,val.toString());
}
printVoid(out);
printHeader(out,"Session information:");
SimpleDateFormat format =
new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS z");
HttpSession session = request.getSession();
if (session!=null) {
printValue(out,"Requested Session Id:",
request.getRequestedSessionId());
printValue(out,"Current Session Id:",
session.getId());
printValue(out,"Current Time:",
format.format(new Date()));
printValue(out,"Session Created Time:",
format.format(new Date(session.getCreationTime())));
printValue(out,"Session Last Accessed Time:",
format.format(new Date(session.getLastAccessedTime())));
printValue(out,"Session Max Inactive Interval"+
" Seconds:",
Integer.toString(session.getMaxInactiveInterval()));
printVoid(out);
printHeader(out,"Session values:");
enum = session.getAttributeNames();
while (enum.hasMoreElements()) {
String key = (String) enum.nextElement();
Object val = session.getAttribute(key);
printValue(out,key,val.toString());
}
}
printVoid(out);
out.println("</pre>");
out.println(" </td>");
out.println(" </tr>");
out.println(" </table>");
out.println(" </body>");
out.println("</html>");
out.flush();
}
}
The output of this listing looks like Figure 4.5.
Request
When a user hits a URL with a servlet at the other end, the Servlet Container creates
an HttpServletRequest object. It passes this object as an argument to the servlet's
service methods (doPut(), doGet(), and doPost()). There is a lot of information in
this object, including the login of the user making this request (getRemoteUser())
and the name of the HTTP method with which this request was made (getMethod()).
However, this exam objective is restricted to header information. Therefore, you
need to know the following HttpServletRequest methods.
• getContentType(). Returns the MIME type of the body of the request, or null
if the type is not known.
• getContextPath(). Returns the portion of the request URI that indicates the
context of the request.
• getCookies(). Returns an array containing all of the Cookie objects the client
sent with this request.
• getLocale(). Returns the preferred Locale that the client will accept content
in, based on the Accept-Language header.
• *getMethod(). Returns the name of the HTTP method with which this request
was made; for example, GET, POST, or PUT.
• getPathInfo(). Returns any extra path information associated with the URL
the client sent when it made this request.
• getProtocol(). Returns the name and version of the protocol the request
uses in the form protocol/majorVersion.minorVersion, for example, HTTP/1.1.
• getRemoteHost(). Returns the fully qualified name of the client that sent the
request.
• getRemoteUser(). Returns the login of the user making this request, if the
user has been authenticated, or null if the user has not been authenticated.
• getRequestURI(). Returns the part of this request's URL from the protocol
name up to the query string in the first line of the HTTP request.
• getRequestURL(). Reconstructs the URL the client used to make the request.
• getScheme(). Returns the name of the scheme used to make this request; for
example, http, https, or ftp.
• getServerName(). Returns the host name of the server that received the
request.
• getServletPath(). Returns the part of this request's URL that calls the
servlet.
/**
* set request attributes
*
* @author Reader@Que
*/
// HTML header
html.append("<html>");
html.append("<head>");
html.append("<title>");
html.append("Servlet Header Example");
html.append("</title>");
html.append("<head>");
html.append("<body>");
Session
A Session is made up of multiple hits from the same browser across some period of
time. The session scope includes all hits from a single machine (multiple browser
windows if they share cookies). Servlets maintain state with sessions. Listing 4.13 is
a modification of a sample servlet that ships with Tomcat. It demonstrates how you
can use session attributes.
Listing 4.13 Servlet That Demonstrates Session Attributes
import java.io.*;
import java.text.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
out.println("<p/>");
out.println("session data" + "<br/>");
Enumeration names = session.getAttributeNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value =
session.getAttribute(name).toString();
out.println(name + " = " + value + "<br/>");
}
out.println("<p/>");
out.print("<form action=\"");
out.print(response.encodeURL("SessionExample"));
out.print("\" ");
out.println("method=POST>");
out.println("Name of Session Attribute:");
out.println("<input type=text size=20 " +
"name=dataname>");
out.println("<br/>");
out.println("Value of Session Attribute:");
out.println("<input type=text size=20 " +
"name=datavalue>");
out.println("<br/>");
out.println("<input type=submit>");
out.println("</form>");
out.println("</body>");
out.println("</html>");
out.println("</body>");
out.println("</html>");
}
}
//returns a page that looks like:
//Session Servlet
//
//session id 9805A5C4C084F5B47788242406C22455
//session created Tue Apr 16 22:11:06 PDT 2002
//session lastaccessed Tue Apr 16 22:13:27 PDT 2002
//
//session data
//publisher = Que
//author = trottier
//scwcd = pass!
To summarize, sessions are what you can use to track a single user over a short
time. You get the session object (HttpSession) from the request object. To track
multiple users over time you must jump to context, covered next.
Context
A Web application includes many parts; it rarely is just one class or one JSP. To help
manage an application, you will sometimes need to set and get information that all of
the servlets share together, which we say is context-wide. An example would be
using a login servlet to create an application-level attribute such as application name
like so:
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
out.print("</title>");
out.print("<head>");
out.print("<body>");
The servlet life-cycle is not obvious. The container calls three methods—namely,
init(), service() and destroy()—in that order. Ordinarily, that is how the
container talks to your servlet. With some containers, you can modify this behavior,
but the exam will assume this order.
EXAM TIP
When is INIT() called? A common question on the exam tests your understanding
of when init() is called. Knowledge of a servlet's life-cycle is crucial to answering
these types of questions. Remember, init() may be called when the server starts
(tell web.xml to load servlet upon startup), when first requested, and sometimes the
container management console will allow you to call it as part of the server
administration. The exam expects you to know that init() will only be called once
per servlet instance, that it is not used to send information back to the browser
(HttpServletResponse is not a parameter), and that it throws a ServletException
to the container that called the servlet if anything goes wrong.
The init method is called first, the first time the servlet is invoked. This happens
one time. However, the service method is called every time a servlet is requested.
Lastly, the destroy method is called one time, upon the removal of the servlet from
memory due either to explicit removal or lack of use (for example, the session
expires). You can configure the container to load certain servlets upon startup
(<load-on-startup/> in web.xml), but most of them will be loaded upon first
request. Either way, the init method is called first. Place in this method things you
will use across requests, like database connections, and class member values such as
finalized constants.
The destroy() method, like init(), is called only once. It is called when the servlet
is taken out of service and all pending requests to a given servlet (that one with the
mentioned destroy() method) are completed or have timed-out. This method is
called by the container to give you a chance to release resources such as database
connections and threads. You can always call super.destroy()
(GenericServlet.destroy()) to add a note to the log about what is going on. You
might want to do this even if only to place a timestamp in there.
Listings 4.15 and 4.16 are sample Web applications (HTML page and servlet
combination) that demonstrate how to use the init(), service(), and destroy()
methods, and when they are called. You could combine them and just have one
servlet, but there are two pieces here to illustrate the relationship between static and
dynamic parts of an application. The first part, Listing 4.15, is the HTML page.
WARNING
DESTROY() is not called if the container crashes! You should log activity from
somewhere other than the destroy() method if a given piece of information is
essential, but might not be logged if the logging functionality is placed in the
destroy() method. This is because the destroy() method is not called if the Servlet
Container quits abruptly (crashes).
Listing 4.15 HTML Page That Works with Servlet in Listing 4.16
Illustrating the Relationship
<html>
<head>
<title>LifeCycle Demonstration Using SQL Server</title>
</head>
<body bgcolor="#FFFFFF">
<p align=center>
<h1>LifeCycle Demonstration Using DB</h1>
<form name="formSearch" method="post" action=
"localhost:8080/examples/servlet/SearchLastNameServlet">
<table border="0" cellspacing="0" cellpadding="6">
<tr>
<td><h2>Search</h2></td>
<td></td>
</tr>
<tr>
<td><b>Last Name</b></td>
<td><input type="text" name="LastName"
value="Fuller">
</td>
</tr>
<tr>
<td></td>
<td align="center"><input type="submit" name="Submit"
value="Submit">
</td>
</tr>
</table>
</form>
</p>
</body>
</html>
NOTE
Servlet Reloading! Servlets are loaded in one of three ways. The first way is when
the Web server starts. You can set this in the configuration file. Reload can happen
automatically after the container detects that its class file (under servlet dir, for
example, WEB-INF/classes) has changes. The third way, with some containers, is
through an administrator interface.
The HTML page contains a form with one field for a last name. When submitted, the
container takes the lastname field and hands it to the servlet in the request object.
This object is where you normally extract requester information. The servlet grabs
the lastname, if any, and builds a SQL WHERE clause with it. Then the servlet
establishes a connection with the database server (I'm using MS SQL Server) and
executes the statement. Then it walks through the resultset getting the data from
each field of every row. Finally, it builds the HTML page and sends it off to the client
browser. While the database portion is not on the exam, it is an excellent example of
how you can take advantage of the methods that are called by the container.
NOTE
Servlet Synchronizing! Servlets are run each in their own thread. When the
synchronized keyword is used with a servlet's service() method, requests to that
servlet are handled one at a time in a serialized manner. This means that multiple
requests won't interfere with each other when accessing variables and references
within one servlet. It also means the processing capabilities of the Servlet Container
are reduced because the more efficient multithreaded mode has been disallowed for
a given servlet that has been declared with the synchronized keyword.
Listing 4.16 is the servlet that queries the database based on the form data. Notice
that you can forgo the above HTML file by appending the FirstName parameter to the
URL like so:
http://localhost:8080/examples/servlet/SearchLastNameServlet?LastName=F
uller. Also, you need to set up a data source with system data source names
(DSNs), whether to a data source that is local to your computer or remote on the
network.
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.ServletConfig;
//common types
final int COMMA = 1;
final int TABLE_COLUMN = 2;
final int TABLE_HEADER = 3;
final boolean DELIMITED = true;
try
{
Class.forName(_driverName);
//warning! userid and password is exposed:
_connection = DriverManager.getConnection
(_connectionString, username, password);
} catch(Exception ex)
{
throw new ServletException(ex.getMessage());
}
}
while(resultset.next())
{
//Not necessary to place in array, but...
String[] field = new String[8];
//warning! these should be in same order as
//DB table field order
//otherwise you can get errors, a Sun todo.
field[0] = ""+resultset.getInt("EmployeeID");
field[1] = resultset.getString("LastName");
field[2] = resultset.getString("FirstName");
field[3] = resultset.getString("Title");
field[4] = ""+resultset.getDate("BirthDate");
field[5] = resultset.getString("City");
field[6] = resultset.getString("Region");
field[7] = resultset.getString("Country");
htmlResult.append( getTableBody(field) );
}
} catch(Exception ex)
{
throw new ServletException(ex.getMessage());
}
//build results
html.append( getTableHeader() );
html.append( htmlResult.toString() );
html.append( getTableFooter() );
html.append( htmlFooter() );
/*
* Prints the table header.
*/
public String getTableHeader()
{
StringBuffer header = new StringBuffer();
header.append("<table border=\"2\">\n");
header.append("<tr>\n");
header.append("<th align=\"left\">EmployeeID</th>\n");
header.append("<th align=\"left\">LastName</th>\n");
header.append("<th align=\"left\">FirstName</th>\n");
header.append("<th align=\"left\">Title</th>\n");
header.append("<th align=\"left\">BirthDate</th>\n");
header.append("<th align=\"left\">City</th>\n");
header.append("<th align=\"left\">Region</th>\n");
header.append("<th align=\"left\">Country</th>\n");
header.append("</tr>\n");
return header.toString();
}
/*
* Prints the table body.
*/
public String getTableBody(String[] field)
{
StringBuffer body = new StringBuffer();
body.append("<tr>\n");
footer.append("</table>\n");
return footer.toString();
}
/*
* Prints the html file header.
*/
public String htmlHeader()
{
StringBuffer html = new StringBuffer();
html.append("<html>");
html.append("<head>");
html.append("<title>LifeCycle Servlet Response" +
"</title>");
html.append("</head>");
html.append("<body bgcolor=\"#FFFFFF\"> ");
html.append("<p align=center><h1>LifeCycle Servlet "+
" Response</h1></p>");
return html.toString();
}
/*
* Prints the html file footer.
* This will change often due to
* marketing and lawyers.
*/
public String htmlFooter()
{
StringBuffer html = new StringBuffer();
html.append("<a href=\"http://localhost:8080/" +
"examples/servlets/LifeCycle.html\">" +
"</b>BACK</b></a>");
html.append("</p>");
html.append("</body>");
html.append("</html>");
return html.toString();
}
}
Once you set up a proper System DSN, or use a fully qualified connection string, the
servlet will query the database. Listing 4.15 shows how you can create an HTML form
to call this servlet. The output of the servlet query looks similar to Figure 4.6.
Using a RequestDispatcher
1.6 Use a RequestDispatcher to include or forward to a Web resource.
There is a matter of timing to consider. You can call an include anytime, but the
forward has to be called before the response is committed. Otherwise you'll throw an
IllegalStateException exception.
IN THE FIELD: REQUEST DISPATCHER PATHS
ServletContext.getRequestDispatcher()— This method uses absolute
paths.
Regarding the forward method, one reason you may want to use it is so you can
dedicate a servlet as the controller. In this way, the controller can filter, preprocess
requests, and manage the transaction. The gotcha here is once a servlet forwards a
request, it loses control. The controller has no capability to regain access directly.
You can create an architecture where requests are returned (forwarded back by a
slave servlet), but the native functionality isn't helpful for this. There is another
problem. When you run Listing 4.17, you'll notice something missing—the URL in the
address bar doesn't change. The client loses path information when it receives a
forwarded request. That means all relative URLs in the HTML become invalid. Your
browser will consider the links broken. Sometimes this doesn't matter, but when it
does, use sendRedirect() instead.
Please see the section "Interfacing with HTML Requests," earlier in this chapter,
where the related objective 1.3 "Retrieve a servlet initialization parameter" is
discussed. Listing 4.8 is especially helpful here because it demonstrates how to
enumerate the context initialization parameter list.
Regarding listeners, you can monitor and react to servlet events by defining listener
objects. These objects have methods that the container invokes when life-cycle
events occur. To make this happen, you define a listener class by implementing a
listener interface. The container will invoke the listener method and pass it
information (methods in the HttpSessionListener interface are passed an
HttpSessionEvent) about that event.
Listing 4.18 demonstrates how you could use the initialization and destruction
events.
Listing 4.18 Listening for a Context Initialization and
Destruction
import java.util.Date;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
o javax.servlet.ServletContextListener.
o javax.servlet.ServletContextAttributeListener.
o attributeRemoved(ServletContextAttributeEvent scab)
Notification that an existing attribute has been removed from the
servlet context.
o attributeReplaced(ServletContextAttributeEvent scab)
Notification that an attribute on the servlet context has been replaced.
o javax.servlet.http.HttpSessionListener.
o HttpSessionAttributeListener.
Chapter Summary
The HTTP methods GET, POST, and PUT are how browsers and Web servers trade data
with each other. The GET retrieves a page without providing much information, while
a POST can package huge amounts of information with its request. A PUT is for
uploading a file. There are events associated with each type of request, such as
clicking a hyperlink sending a GET request, but clicking a form button sends a POST
request.
KEY TERMS
• Redirection
• Servlet Life-Cycle
• Servlet attribute
• Context parameters
• Application session
• listeners
The most important objects in the servlet process are the request and response
objects. The request parameters for the servlet are the strings sent by the client to
the Servlet Container. The container parses the request and puts the information in a
HttpServletRequest object which is passed to the servlet. Going the other way, the
container wraps the response parameters with the HttpServletResponse object which
is passed back to the container.
Containers have the idea of scope. When something has Context scope it is
application-wide and all users can share data. Session scope means one user can
share data across page views, but other users can't. Request scope restricts data to
only that page. The container also manages the servlet life-cycle by initializing a
servlet with a call to the init() method, a call to the service() method upon every
request, and by calling a servlet's destroy() method just prior to removing it from
memory. The container also allows you to monitor context and session events with
listeners that are event-driven triggers. When an attribute changes, special targeted
methods are called. In them, you can define special actions such as "add a note to
the log every time the user count changes."
A2: The GET, POST, HEAD, PUT, DELETE, TRACE, and OPTIONS methods are supported by
HttpServlet. Refer to the section, "Interfacing with HTML Requests."
3:What objects are passed to the servlet's service() method?
A3: ServletRequest and ServletResponse objects are passed to the servlet's service
method. Refer to the section, "Interfacing with HTML Requests."
4:What is a distributable application?
A5: When the synchronized keyword is used with a servlet's service() method,
requests to that servlet are handled one at a time in a serialized manner. This
means that the processing capabilities of the Servlet Container are minimized.
Refer to the section, "Servlet Life-cycle."
6:What is the relationship between an application's ServletConfig object and
ServletContext object?
A6: An application's ServletConfig object contains its ServletContext object and
provides access to this object via its getServletContext() method. Refer to the
section, "Web Application Context."
7:What mechanisms are used by a Servlet Container to maintain session
information?
A7: Cookies, URL rewriting, and HTTPS protocol information are used to maintain
session information. Refer to the section, "Session."
8:What are the four events that are defined in the Servlet API?
A8: The four events that are defined by the Servlet API are HttpSessionEvent,
HttpSessionBindingEvent, ServletContextEvent, and
ServletContextAttributeEvent. Refer to the section, "Servlet Life-cycle."
9:How are request dispatchers used?
A9: Request dispatchers are used to forward requests to other servlets or to include
the results of other servlets. Refer to the section, "Using a RequestDispatcher."
Exam Questions
1:Which of the following methods are defined in the Servlet interface?
A. init()
B. service()
C. finalize()
D. destroy()
A1: C. The finalize() method is not defined by the Servlet interface. Refer to the
section, "Servlet Life-cycle."
2:Which of the following objects are passed to a servlet's service() method?
A. ServletRequest
B. HttpServletRequest
C. ServletResponse
D. HttpServletResponse
A2: A, C. ServletRequest and ServletResponse methods are passed to the
service() method. Refer to the section, "Servlet Life-cycle."
3:By default, how many instances of a servlet are created by a Servlet Container?
A. One
A. ServletException
B. InitializationException
C. UnavailableException
D. ServletContextException
A4: A, C. The Servlet API defines ServletException and UnavailableException. Refer to
the section, "Servlet Life-cycle."
5:Which of the following are used by Servlet Containers to maintain session
information?
A. cookies
D. URL rewriting
A5: A, C, D. Hidden form fields are not used by Servlet Containers to maintain session
information. Refer to the section, "Form Parameters."
6:Which of the following event listeners are defined by the Servlet API?
A. HttpSessionBindingListener
B. HttpSessionEventListener
C. HttpSessionParameterListener
D. HttpSessionAttributeListener
A6: A. Only HttpSessionBindingListener is defined by the Servlet API. Refer to the
section, "Servlet Life-cycle."
7:Which of the following methods are defined by the RequestDispatcher interface?
A. dispatch()
B. include()
C. redirect()
D. forward()
A7: B, D. The RequestDispatcher interface defines the include() and forward()
methods. Refer to the section, "Using a RequestDispatcher."
8:Which of the following is the name of the cookie used by Servlet Containers to
maintain session information?
A. SESSIONID
B. SERVLETID
C. JSESSIONID
D. CONTAINERID
A8: C. The JSESSIONID cookie is used by Servlet Containers to maintain session
information. Refer to the section, "Session."
7. Tomcat— an implementation of the Java Servlet 2.2 and JavaServer Pages 1.1
Specifications—http://jakarta.apache.org/tomcat/index.html.
Servicing requests from users on the Web means you will sometimes receive bad
information. Also, you may make a mistake in your code. How do you handle these
conditions in servlets? This chapter discusses error and exception handling.
There are two categories of problems you will face. One is from Java itself and your
code. For example, you may try to write a note to the log file, but that file is locked
at the moment so the write attempt fails. That will throw an exception. The other
category regards the user's request, where you might get a corrupt or incomplete
request. These error codes that you will work with are based on the Hypertext
Transfer Protocol (HTTP).
The main focus of this chapter is servlet exceptions and HTTPse error codes (those
associated with the client), how they are used, and the effect they have on the
servlet behavior. So this chapter covers objectives 4.1 and 4.3 from Section 4,
"Designing and Developing Servlets to Handle Server-side Exceptions," of the Sun
preparation guide.
4.1 For each of the following cases, identify correctly constructed code for
handling business logic exceptions, and match that code with correct
statements about the code's behavior:
• Exceptions and errors are never nice, but with a GUI application, at least you
can expect a person at the console to interact, perhaps intercept, an
application's bad behavior. With a server, this isn't so.
You must handle the exceptions assuming the server is operating completely on its
own. This chapter introduces you to the way servlets throw and manage exceptions,
including the steps you need to take to make sure your server catches exceptions
properly.
• The purpose of this objective is to teach you how to write data into the log
file. This objective is related to the previous one because you often write data
into a log file immediately after throwing an exception.
OUTLINE
Introduction
sendError Method
setStatus Method
WebApp Log
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• Take some time to study the difference between the two approaches to telling
the client a problem has occurred.
Introduction
The way in which you create and manage exceptions with servlets is slightly different
from how you do this with standalone applications.
WARNING
The exam is looking for SENDERROR and SETSTATUS! While there are many ways to
customize error handling, do not expect weird customized exception routines on the
exam. Also, notice that you use the response object (HttpServletResponse), not the
request object, to tell the browser that there is a problem.
You must be aware of both the severity and type of error to properly tell the client
what went wrong. Just how damaging is the problem? Your error handling logic
needs to determine the most appropriate severity for a particular error.
After receiving a request, the server responds. It returns an HTTP response message.
The first line of this response message is called the status line. The status line has
three parts. They are, in this order, protocol version, numeric status code, and status
textual phrase. For details, such as the fact that each element is separated by space
characters, and CR or LF are disallowed except in the final CRLF sequence, please
see RFC 2616. This status code is what you are setting when you use sendError and
setStatus methods.
You have surely encountered the 404, NOT FOUND message at some Web sites. This
tells you that the URL is bad. Notice that number 404. This is an example of a status
code, a three-digit integer code. The first digit of the status code defines the class of
response, while the last two digits do not have categories, although they are defined
in the standard. Table 5.1 provides a list of the HTTP status codes (only the first digit
is significant).
Table 5.1. Status Codes
4XX Client Error The request contains bad syntax or cannot be fulfilled.
5XX Server Error The server failed to fulfill an apparently valid request.
While Table 5.1 describes a five-part scheme for the status codes, we will primarily
be interested in the Server Error category (5XX) codes.
Internally, the sendError() and setStatus are closely related. In fact, they both set
the error message to be displayed by the client and the status code used by the
client. The default status code is HttpServletResponse.SC_OK ="OK"; however,
there are a few dozen standard codes.
Table 5.2 provides a list of status codes. These codes were defined by the W3C and
are sanctioned by the Internet Society (ISOC). The constant names, quoted
messages that get displayed in the browser, and code descriptions are a combination
of the servlet specification and Tomcat's implementation of that specification. The
exam will not test your memory of these directly. However, taking five minutes to
study this table will help you understand what these codes do and figure out which
ones you need to use with the sendError and setStatus methods. Notice that the
RFC column provides the Request For Comment document and section, the Internet's
way of documenting standards. Also, some browsers allow the user to hide "friendly"
error messages. If they do that, they will not see many of these errors, even if they
occur.
Table 5.2. HTTP Status Codes
the server.
The servlet is just as prone to logic errors and bugs as standalone applications. Java
has a smart facility for handling them in both environments. Let's look at a very
simple example of how you might handle an error in a servlet. The ErrorServlet
servlet illustrates the use of the sendError() method. It takes an error code as a
parameter and an optional custom message associated with that error (see Listing
5.1).
response.sendError(HttpServletResponse.SC_FORBIDDEN,
"Sorry, restricted to geeks.");
}
}
Compile the ErrorServlet file and hit the servlet with your browser.
The container will send an error message to the client. You should see a page that
looks like Figure 5.1.
sendError Method
The sendError method sends an error response to the client using the specified
status. Using this method clears the buffer. The server creates an HTML-formatted
server error page. This page contains a default, or the message you provide, as an
argument. It also sets the content type to "text/html", even if you changed this, but
leaves cookies and other headers unmodified.
WARNING
Do Not Send Data to Client After SENDERROR()! Once the sendError method is
invoked, all buffered output will be discarded. If data has been written to the
response buffer but not returned to the client (not committed), the data is cleared
and replaced with the data sent by the sendError method. The sendError method
will commit the response, if it has not already been committed, and terminate it.
Data written to the response afterward is ignored. However, if you write data to the
response buffer and try to commit it after sendError has been invoked, an
IllegalStateException will be thrown.
The sendError method will set the appropriate headers and content body for an
error message to return to the client. An optional String argument can be provided to
the sendError method, which can be used in the content body of the error. Using
this method will commit the response (if not already committed) and terminate it.
The data stacked in the output stream to the client before calling sendError()
method is ignored.
Internally, the servlet base classes prevent you from writing to the output stream
after calling sendError(). In the write-to-stream methods there is a test for a
previous error in the servlet that looks like this:
//suspended is a flag set once output is committed
if (suspended)//true if sendError has been called
throw new IOException
(sm.getString("responseBase.write.suspended"));
That is why you can't add to the outputstream after calling sendError().
The best way to understand the sendError() method is to look at it directly. Listing
5.2 (prettied a bit) is how Tomcat implements the specification on sendError():
if (included)
return; //Ignore any call from an included servlet
setError();
You can make better use of this method if you create a wrapper for it. You might
want to do this if you care to send custom messages to the client rather than accept
the default ones provided by the container. You can write a wrapper like the one in
Listing 5.3.
if(message.equals("NONE"))
{
response.sendError(HttpServletResponse.SC_ FORBIDDEN);
} else
{
response.sendError(HttpServletResponse.SC_ FORBIDDEN,
message);
}
//perhaps your own history log:
//internalLog(code, message);
}
setStatus Method
The setStatus method sets the status code for a given response. Use this method,
instead of sendError, when there is no exception or serious error (such as Forbidden
page). If there is a serious error, the sendError method should be used; otherwise
use setStatus. Like the sendError method, using this method clears the buffer, but
leaves cookies and other headers unmodified.
if (included)
return; //Ignore any call from included servlet
this.status = status;
this.message = message;
}
As you can see, this method has been deprecated because the message functionality
isn't reliable. The setStatus method will remain (the one taking only a status code),
but without a message parameter in a future version, I predict. You can write a
wrapper for the setStatus method like that shown in Listing 5.5.
WARNING
Containers don't always follow the specification! Clearly, Tomcat does not clear
the buffer as the specification notes. The specification doesn't make sense on this
point; the way Tomcat implemented it is better. However, since other containers may
follow the specification here and the exam will be based on the specification, assume
that is how it actually works.
produced this:
pre setStatus message.
post setStatus message.
WebApp Log
4.3 Identify the method used for the following:
The Server Configuration File defines the component elements that comprise the
"Server," a singleton element that represents the entire JVM. Two of these elements
are the Access log and the Activity log. These are simple text files to which the
container appends messages. While containers differ, Tomcat implements the
specification very closely, except for just a few things. Let's look at how Tomcat uses
logs.
By default, log files are created in the "logs" directory relative to the home directory
of Tomcat installation ($CATALINA_HOME). You can specify a different directory, using
either a relative (to $CATALINA_HOME) or absolute path, with the "directory" attribute
in the server.xml file. Different containers handle this in various ways, but Tomcat
creates two new files, access and activity, every time you start the server.
Tomcat implements several log files. One of them is the Global log file (for example,
catalina_log.2002-12-25.txt). Its contents look like this after starting, stopping, and
starting again:
2002-04-25 13:52:29 HttpConnector Opening server socket ...
2002-04-25 13:52:34 HttpConnector[8080] Starting ...
2002-04-25 13:52:34 HttpProcessor[8080][0] Starting ...
2002-04-25 13:52:34 HttpProcessor[8080][1] Starting ...
2002-04-25 13:52:34 HttpProcessor[8080][2] Starting ...
2002-04-25 13:52:34 HttpProcessor[8080][3] Starting ...
2002-04-25 13:52:34 HttpProcessor[8080][4] Starting ...
2002-04-25 14:33:36 HttpProcessor[8080][4] Stopping ...
2002-04-25 14:33:36 HttpProcessor[8080][3] Stopping ...
2002-04-25 14:33:36 HttpProcessor[8080][2] Stopping ...
2002-04-25 14:33:36 HttpProcessor[8080][1] Stopping ...
2002-04-25 14:33:36 HttpProcessor[8080][0] Stopping ...
2002-04-25 14:33:36 HttpConnector[8080] Stopping ...
2002-04-25 14:34:52 HttpConnector Opening server ...
2002-04-25 14:34:55 HttpConnector[8080] Starting ...
2002-04-25 14:34:56 HttpProcessor[8080][0] Starting ...
2002-04-25 14:34:56 HttpProcessor[8080][1] Starting ...
2002-04-25 14:34:56 HttpProcessor[8080][2] Starting ...
2002-04-25 14:34:56 HttpProcessor[8080][3] Starting ...
2002-04-25 14:34:56 HttpProcessor[8080][4] Starting ...
When something breaks, this log is somewhat helpful in that you can see what
thread is broken. A more helpful log is Tomcat's access log (such as
localhost_access_log.2002-12-25.txt), which appends the following line after I
request the previous servlet above with
http://localhost:8080/examples/servlet/ErrorServlet:
127.0.0.1 - - [25/Dec/2002:14:23:53 -0800]
"GET /examples/servlet/ErrorServlet HTTP/1.1" 200 75
The log which is most interesting to us is the file localhost_examples_log.2002-04-
25.txt (other containers will use a different name and perhaps a different location).
This is the one that is written to when you use the logging functionality in the servlet
environment.
Listing 5.6 is a logger wrapper. It creates a snapshot of the request parameters and
prints it to the log file. You might not want all this information, but it illustrates what
you can do.
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>Servlet Error Handling " +
"Example</title></head>");
out.println("<body>");
out.println(logMessage);
out.println("</body>");
out.println("</html>");
}
There is one more wrinkle to the log feature that you need to know for the exam.
You can pass an exception object to the log method. If you add the following code to
the preceding LogServlet code:
try
{
int zero = 0;
int problem = 10/zero;
} catch (Exception e)
{
log("Oops, division by zero.", e);
//optional:
//throw new ServletException(e);
}
NOTE
GenericServlet has log method! The abstract GenericServlet class has a log
method, log(String), which writes the specified message to a servlet log file,
prepended by the servlet's name.
The logger will add the following to the log file (localhost_examples_log.2002-012-
25.txt):
2002-04-25 22:00:09 org.apache.catalina.INVOKER.LogServlet:
Oops, division by zero.
java.lang.ArithmeticException: / by zero
at LogServlet.service(LogServlet.java:38)
at javax.servlet.http.HttpServlet.service(...)
//33 more lines of error messages removed for space
at java.lang.Thread.run(Thread.java:536)
Chapter Summary
One of the first hurdles in servlet design you'll encounter is exception handling. The
exception features of the servlet API are decent. The exam expects you to know how
to handle exceptions. There won't be many questions on this, but you will see a few.
KEY TERMS
• exception
• sendError()
• setStatus()
• Logging
• Status codes
• Error codes
There are other ways to analyze application events and performance. There is the
Jylog project (jylog.sourceforge.net/) which is an open source logging tool built with
the Java Platform Debugger Architecture (JPDA) SDK 1.3
(java.sun.com/products/jpda/). It eliminates the tedious logging code that will litter
your source. Another excellent effort by the Apache group is the log4j project. log4j
enables logging at runtime without modifying the application binary. That group is
trying to design the package so that you don't incur a heavy performance cost. It has
a nice architecture where the logging behavior is controlled by editing a configuration
file. These applications are a boon to you when you need detailed context for
application events and failures. However, for the exam, you only need to know how
to call the log method, which has two signatures, both with a string message and
one with an exception.
A1: A status code is a discrete mechanism where the server and client talk to each
other employing a predefined vocabulary of codes. These codes also help the client
keep the user informed on the progress of a request. See "Introduction."
2:What classifications are there for status codes?
A2: The default status code for requests is 200 ("OK"). There are five types of status
codes defined by the HTTP standard (not Sun). 1XX is informational. It indicates a
request was received and is continuing to be processed. All is well. 2XX says that
there was success. So, the request was successfully received, understood, and
accepted. 3XX is used for redirection. It tells the browser to try somewhere else
and further action must be taken in order to complete the request. 4XX is a
message from the server telling the client that the request contains bad syntax or
cannot be fulfilled. The last class of status codes is 5XX, which indicates a server
error. The server failed to fulfill a syntactically valid request. See "Introduction."
3:How does logging work in servlets?
A3: The log() method writes a specified message to a servlet log file. This can be
used as a debug log or simply an event log. The name and type of the servlet log
file is specific to the servlet container. Tomcat allows you modify this. See
"WebApp Log."
4:What would be the preferred storage location for application events?
A4: When you are working with servlets, it is hard to see what is going on. You will
probably need to log servlet activity. The preferred storage location for application
events is a log file. You can use your own or use the built in logging functionality in
servlets. See "WebApp Log."
5:How does sendError() work?
A5: When you call the sendError method, the server responds with a status line with
the protocol version and a success or error code (this is what sendError affects
directly). Of course, it also returns a MIME-like message containing server
information, entity meta information, and body content. See "Returning an Error
Code to the Client."
6:What is the difference between sendError() and setStatus()?
A6: The setStatus method sets the status code for a given response. Use this
method, instead of sendError, when there is no exception or serious error (such
as Forbidden page). If there is a serious error, the sendError method should be
used; otherwise use setStatus. Like the sendError method, using setStatus
clears the buffer, but leaves cookies and other headers unmodified. See "Returning
an Error Code to the Client."
Exam Questions
1:The sendError() method sends what type of information to the client?
A. Response footer.
B. Response header.
C. Content body.
A. response.sendError(HttpServletResponse.SC_FORBIDDEN, "Sorry,
restricted to geeks.");
B. request.sendError(HttpServletResponse.SC_FORBIDDEN, "Sorry,
restricted to geeks.");
C. request.sendError(HttpServletResponse.SC_FORBIDDEN);
A. 2XX.
B. 3XX.
C. 4XX.
D. 5XX.
A3: B. 3XX is used for redirection. The other codes are 2XX for continuation, 4XX for
client error, and 5XX for server error. See "Introduction."
4:The status codes have been defined by whom?
A. The DSN group.
D. response.sendError(HttpServletResponse. SC_NOT_ACCEPTABLE,
"Sorry, your crentials are invalid. Please try again.");.
A5: D. This is the correct way to send a "Not Acceptable" status code of 406. The
other answers are correct syntax, but don't send the proper status code to the
client. See "Returning an Error Code to the Client."
6:Which method is best for telling the client that all went well and the request was
processed successfully?
B. setHeader()
C. setStatus()
D. setIntHeader()
A6: A. This is a difficult question. B, C, and D can be used to send information to the
client. C is close because it is sometimes used to send an "OK" status of 200 back
to the client. However, A is the correct answer. This particular task should be left
to the container. See "Returning an Error Code to the Client."
7:Which method commits the response, effectively terminating it?
A. sendError()
B. setHeader()
C. setStatus()
D. finalize()
A7: A. This is the only method that actually terminates the request. sendError()
commits the response, if it has not already been committed, and terminates it. No
further output to the client can be made because data written to the response
after this method is called is ignored. See "Returning an Error Code to the Client."
8:How can you return an exception object to the client?
B. Use sendError.
C. Use setStatus.
D. Use sendException.
A8: B. Sending an exception object is not possible without a lot of tweaking. This
action is not mentioned anywhere in the specification. See "Returning an Error
Code to the Client."
9:Which of the following will throw an IllegalStateException exception?
A. setIntHeader(long)
B. setHeader(long)
Answers marked with an asterisk (*) indicate that the specific material covered by
the question has a very low probability of being on the exam in that form. These
questions were included because the concepts they tap represent important
background knowledge or because they are important to developing your overall
professional skills.
9. WebTrends— http://www.webtrends.com.
5.1 Identify the interface and method for each of the following:
• This section of the exam covers your familiarity with session objects within
servlets. Sun gave session functionality ample attention, so it is not hard to
learn. For example, it is easy to retrieve a session object across multiple
requests to the same or different servlets within the same WebApp. You can
store and later retrieve objects from the session object. Lastly, you can
respond to triggers that fire upon a change to the session object state (for
example, adding an object to or removing an object from a session). Session
objects help maintain client state in a consistent manner. This is a better way
to maintain state than most custom approaches.
• The exam will present scenarios which may or may not invalidate a session
object. In other words, what will kill a session? For example does viewing
another page invalidate a session? Does leaving your desk do so? This section
answers these questions and discusses exactly how to kill a session.
OUTLINE
Introduction
Event Listeners
Invalidating Sessions
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• The key to this section of the exam is to understand how servlets implement
the session object functionality.
• There aren't many methods to know, but scope is another matter. If you are
not careful, you can get confused and lose track of what you added to a
session and what you didn't.
• Each session object lives for the duration of a single client accessing the Web
server. There are a few rules, such as the timeout where the session dies if
inactivity lasts more than 20 minutes (time is configurable).
Introduction
When one page needs to share information with another, the scope of the data
broadens beyond processing a single request. When that happens, you must send
the data from one page to the server and from the server to the next requested
page, whether it be the same page or another page altogether. There are several
ways to share state information between requests. However, the primary way is to
use sessions, the topic of this chapter.
Sharing State Information Between Requests
There are many techniques in use today to share state information between
requests. This chapter focuses on using sessions to maintain state. To appreciate
sessions, let us first look at a few others ways to maintain state. One way is to
persist the data in a form field between views of the same page.
Let's study an example. For example, suppose you want to maintain the first and last
name of a user between page views. Listing 6.1 represents all that is required to
persist data between views of the same page generated by a servlet.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* A simple servlet.
* SCWCD Exam Objective 5.1 = session objects
*
* @author Reader@Que
*/
out.println("</body>");
out.println("</html>");
}
}
Listing 6.1 showed you an example of how you can persist data between views of the
same page. See Figure 6.1 for a picture of the output.
Figure 6.1. You can persist data between views of the same
page using form fields.
Listing 6.2 is the HTML the servlet generates and sends to the browser after the user
typed Patricia and Devyn in the fields.
You basically persist the data between views of the same page by receiving the field
value and populating the field again with the same value when returning the form in
your response. There are times when this is appropriate (don't make the user retype
a field). However, this isn't a good way to persist data, because the data lives only in
the field value and nowhere else. Another trick is to use hidden fields.
Another old tactic you can use is to "hide" user submitted information in a form with
the HIDDEN tag. This tag just sits in the page, but the browser doesn't display it to
the user. The following is an example:
<!-- formHandler is servlet that handles form submission -- >
<form action="formHandler">
<input name="firstName" value="" >
<input name="userID" value="23AX" type="hidden">
<input type=submit>
</form>
This HTML snippet specifies that the firstName and the userID field values be sent
to the formHandler servlet. The firstName field is visible on the screen, but the
userID field is not; it is hidden. Be careful with hidden fields. While the hidden field's
value isn't displayed on the page, the user can see the value of the hidden field by
viewing the HTML source of the document. Even so, at least you can persist data
between pages with hidden fields. This is a very shallow method. It is insecure. Don't
use it if the data is sensitive.
The next step on our ladder of sophisticated means to persist data between pages is
using cookies. A cookie is a tiny text file that is maintained by the browser to do
things like store unique IDs. They are normally small (~1KB) and saved in the OS
cookie directory or folder. There are numerous browsers that handle cookies in
various ways. For example, in Windows, the following short list shows you how a few
versions of Explorer stores cookies:
Figure 6.2 shows you where they are on my Dell Inspiron running Windows 2000
Professional.
Cookies have had many lives and deaths, it seems. In the old days they were used
for all manner of things, including storing personal data like passwords. The
popularity of doing so has waned. Today, especially with servlets, it is better to store
most information in sessions than cookies. But it is still important to understand
cookies before discussing sessions.
Figure 6.2 is typical of a cookie folder. As you can see, there are many cookies on my
machine. Those shown in Figure 6.2 are only a few that have been created on my
Dell. Originally, folks put actual data like names and addresses in cookies because
there wasn't anywhere else to save these valuable pieces of data. Today, the
information in a cookie is primarily an identifier of sorts. The following cookie text
was placed on my hard disk by DoubleClick. I never saw it happen. The reason it
happened to me is companies (for example, Netscape) hire DoubleClick to manage
their online advertisement. Companies like DoubleClick can charge more for their
advertising services if they can figure out what I like. When a user visits Netscape, a
DoubleClick cookie is created and an identifier is placed in it by DoubleClick.
DoubleClick records which pages on Netscape you visit. Also, if you happen to visit
another vendor who has a contract with DoubleClick, that movement is recorded too.
Now, DoubleClick knows a little more about you so it can throw ads at you that you
are more likely to like.
Vendors implement session IDs differently. Let us dig into Tomcat to see how it
handles sessions IDs. The following snippet, edited for clarity, is how a session ID is
generated:
/**
* Generate and return a new session identifier.
*/
protected synchronized String generateSessionId() {
Most of the cookies on our machines are not used for anything sinister. You can
thwart all this by turning off cookies and images, but the Web suddenly becomes
bland. For example, you can almost thwart companies like DoubleClick from invading
on your privacy by making a change in your browser's configuration. You can do this
in IE by going to View, Internet Options, Advanced, selecting Prompt before
accepting Cookies, and clicking OK.
Cookies aren't all cloak and dagger, though. In fact, they are used for good far more
often than bad. For example, when I go to Amazon.com, I get a familiar view
because they remember what I did on my last visit. Amazon can do that because it
placed a file on my machine called administrator@amazon[1].txt (the browser
actually does this) containing this:
session-id
432-5447995-1125358
amazon.com/
0
4322765824
89901156
321345632
79444758
*
session-id-time
8731881600
amazon.com/
0
9985765824
44191156
185745632
09789758
*
ubid-main
0883061-5210078
amazon.com/
0
6796341376
69581269
777869456
29476039
*
x-main
3xBkjhwcqmPgTz7hgffU8UoFvMDSWX
amazon.com/
0
7896341376
1969969
939053232
9770408
*
I like the idea of Amazon tracking my activities. They are open about it and I can
stop them any time I wish. I hate it when other companies do so stealthily.
It isn't just DoubleClick and Amazon that need cookies: You do, too. You can create
cookies with the cookie functionality of the response object. In fact, if you want to
perform any real communication between views, you need to use cookies. Cookies
aren't a big focus of the exam, but I thought you might like to understand how they
work in servlets.
Maintaining client state has always been important. With the Internet it is hard to do
because the very nature of the Internet is packet switching, which means
asynchronous communication. There is a disconnect between Web page requests due
to the Internet's nuclear-war-withstanding, stateless protocol. However, some of your
applications will require a series of client requests to be associated with one another.
The best way we have for maintaining state, out of the Java box, is called sessions.
To support applications that need to maintain state, Java Servlet technology provides
an API for managing sessions and allows several mechanisms for implementing
sessions.
To summarize, the following are the four most frequently used methods for persisting
data between views:
• Hidden form field: Data is placed in the HTML in a hidden form field.
• Query string: Some data is appended to the query string or a hyperlink in the
HTML.
• Cookie: A small text file created by the browser that stores data sent by the
server.
These four approaches are the ones most often used; however, session technology
does more for you. The following section describes how Java uses sessions to help
you maintain client state.
• isNew(): This tells you whether the client knows about the session. In other
words, the has session been created by the server, but the client hasn't
acknowledged receiving the session ID yet.
The preceding methods are the ones that will appear on the exam. The following
sections will show you how to use them and in what context they are best suited.
This exam objective addresses the manner in which you use sessions in servlets;
namely, to set and get information into and out of a session object while processing
a request. Listing 6.3 is a guest listing of sorts. This is how Tomcat implements the
capability to create a session. It usually helps to look under the hood to see how
something is done before we discuss how to use that same functionality.
session = manager.createSession();
if (session != null)
return (session.getSession());
else
return (null);
}
/**
* Return <code>true</code> if the session identifier
* included in this request came from a cookie.
*/
public boolean isRequestedSessionIdFromCookie()
{
if (requestedSessionId != null)
return (requestedSessionCookie);
else
return (false);
}
/**
* Return <code>true</code> if the session identifier
* included in this request came from the request URI.
*/
public boolean isRequestedSessionIdFromURL()
{
if (requestedSessionId != null)
return (requestedSessionURL);
else
return (false);
}
Listing 6.3 shows you how Tomcat handles your request to create a session object.
Now let us make use of that functionality. Listing 6.4 demonstrates some basic
techniques of how to create a cookie and session, place data into them, and finally
get that same data back out. This is a derivation of several excellent code samples I
found in the Tomcat source distribution.
/**
* Return the session associated with this Request,
* creating one if necessary and requested.
*
* @param create Create a new session if none exist
*
* To make sure the session is properly maintained,
* you must call this method before the response is
* committed. If the container is using cookies to
* maintain session integrity and is asked to create
* a new session when the response is committed,
* an IllegalStateException is thrown.
*/
HttpSession session = request.getSession(true);
String cookieName =
request.getParameter("cookiename");
String cookieValue =
request.getParameter("cookievalue");
if (cookieName != null && cookieValue != null)
{
Cookie cookie =
new Cookie(cookieName, cookieValue);
response.addCookie(cookie);
}
out.println("<html>");
out.println(" <head>");
out.println(" <title>Session Detail " +
"Report</title>");
out.println(" </head>");
out.println(" <body>");
out.println(" <center>");
out.println(" <h2>Session Detail Report</h2>");
String url=request.getScheme()+
"://"+request.getServerName()+
":"+request.getServerPort()+
request.getRequestURI();
printHeader(out,"Session information:");
SimpleDateFormat format = new
SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSS z");
printValue(out,"Requested Session Id:",
request.getRequestedSessionId());
printValue(out,"Current Session Id:",
session.getId());
printValue(out,"Current Time:",
format.format(new Date()));
printValue(out,"Session Created Time:",
format.format(new Date(session.getCreationTime())));
printValue(out,"Session Last Accessed Time:",
format.format(new Date(session.getLastAccessedTime())));
printValue(out,"Session Max Inactive " +
"Interval Seconds:",
Integer.toString(session.getMaxInactiveInterval()));
printVoid(out);
printHeader(out,"Session values:");
Enumeration enum = session.getAttributeNames();
while (enum.hasMoreElements())
{
String key = (String) enum.nextElement();
Object val = session.getAttribute(key);
printValue(out,key,val.toString());
}
printVoid(out);
out.println(" </td>");
out.println(" </tr>");
out.println(" </table>");
out.println(" </body>");
out.println("</html>");
out.flush();
}
We will first look at how objects bound to a session may listen to container events,
notifying them that sessions will be passivated or sessions will be activated. This
interface is HttpSessionActivationListener extends java.util.EventListener.
The methods are
NOTE
Session Moving Between JVMs The specification dictates that a container that
migrates a session between VMs or persists sessions is required to notify all
attributes bound to sessions implementing HttpSessionActivationListener. This
has to do with distributed Web apps, covered in Chapter 10, "Web Applications."
These two methods call the method by the same name in the listener when the
session is created or destroyed.
The listener interface that enables an object to monitor changes to the attribute lists
of sessions within a given Web application is HttpSessionAttributeListener
extends java.util.EventListener. The methods that concern us here are
• attributeAdded(HttpSessionBindingEvent se): This is the notification that
an attribute has been added to a session.
You would use these methods when monitoring attributes within a session. Perhaps
you'll want to make an entry in the log every time a user visits a certain URL.
The last group of listeners are concerned with binding and unbinding to a session.
This event listener causes an object to be notified when it is bound to or unbound
from a session. The interface is HttpSessionBindingListener extends
java.util.EventListener. This will be triggered when a servlet is coded to
explicitly unbind an attribute from a session, due to a session being invalidated or a
session timeout. The methods that concern us here are
You might want to know when an object is added or removed from a session to
handle, say, a shopping cart checkout.
Listing 6.5 shows you a small snippet of creating a session, binding and unbinding
attributes to it, and then destroying the session. Use it with Listing 6.6 to see how to
monitor attributes with listeners.
Invalidating Sessions
5.2 Given a scenario, state whether a session object will be invalidated.
EXAM TIP
When is session invalid Surfing to another Web site does not invalidate a session,
but quitting the browser does. The user can surf from your page to somewhere else
and back again without losing the session. The session will remain intact unless the
user was away longer than the timeout.
This section helps you answer exam questions regarding what invalidates a session.
The exam will present a scenario and ask you whether a session object will be
invalidated. This can be tricky. For example, what happens when the user leaves her
desk or closes her browser?
• The user closes all browser windows. Notice, that the session will timeout
rather than directly triggering a session invalidation.
• The server is stopped or crashes. Notice that this event might not trigger a
session invalidation. A Web container that permits failover might persist the
session and allow a backup Web container to take over when the original
server fails.
• You can set the default timeout in the web.xml file (<web-app><session-
config><session-timeout>). (See Chapter 10 for more information about
the deploy descriptor file, web.xml.)
WARNING
Default Timeouts Vary! You should be careful about the default timeout value.
Some containers come configured for 20-minute timeouts, but this is not a hard rule.
Tomcat is configured for 30-minute timeouts, for example. All containers are
configurable though.
You append the session ID in URLs by calling the response's encodeURL(URL) (or
encodeRedirectURL()) method on all URLs returned by a servlet. This method
includes the session ID in the URL only if cookies are disabled; otherwise, it returns
the URL unchanged. The following snippet shows you how to do this:
response.setContentType("text/html");
out.println("<P>");
out.print(response.encodeURL("ExampleURL"));
out.println("<P>");
out.print(response.encodeURL("ExampleURL?name=" +
"university&value=Vanguard"));
out.println("</center>");
out.println("</body>");
out.println("</html>");
out.println("</body>");
out.println("</html>");
}
NOTE
JSESSIONID! Session tracking is maintained when cookies are off, with the
jsessionid attribute being appended to query strings using the encodeURL() and
encodeRedirectURL() methods.
When I first ran Listing 6.7, my cookies were turned on. I saw this in the browser:
ExampleURL?name=university&value=Vanguard
I then turned off cookies and received this on the next visit:
ExampleURL;jsessionid=62A027E37975F305B07555859780E423?name=university&
value=Vanguard
As you can see, the jsessionid attribute gets added. You will probably see this
attribute mentioned on the exam.
Chapter Summary
The session functionality is not extensive in servlets. However, it is enough to get
most jobs done. You can use a session in servlets to maintain state between visits.
There is a time limit (usually less than an hour). To get the current session in a
servlet, you call the getSession() method of HttpServletRequest. You have one
parameter to think about. If you don't provide a boolean (no-arg variation of
getSession) then this method will create a session if no session exists. However, if
you provide a true boolean, the container will automatically create a new session if it
doesn't already exist. The point of providing a true boolean is to make your
intentions explicit even though providing no argument has the same effect. You can
provide a false to make sure a session is not created should one not exist. You get a
session like so:
HttpSession session = request.getSession(true);
KEY TERMS
• Session
• Session ID
• Session Timeout
• Session Attribute
• Session Events
• Listeners
A1: The following are the four most frequently used methods of persisting data
between views: Field-field value persistence, placing data in the HTML in a hidden
form field, appending data to the query string or a hyperlink in the HTML, and
using cookies. See "Sharing State Information Between Requests," earlier in this
chapter.
2:What is the purpose of the HttpSession object?
A2: The servlet container uses the HttpSession interface to create a session between
an HTTP client and an HTTP server. You use it to create a session that lasts for a
specified time period, across page requests from a single user. This interface
allows you to view and manipulate information about a session and bind objects to
sessions, too. See "Using Session Objects," earlier in this chapter.
3:We use sessions now. Are cookies still important?
A3: Cookies are still important. While we don't normally store data in cookies, we still
need them to store the session ID, without which it is hard to maintain state. See
"Sharing State Information Between Requests," earlier in this chapter.
4:How do you know when an event has occurred?
A4: The listener interface allows an object to be notified when a session attribute
changes within a given Web application. You would use these methods when
monitoring attributes within a session. There are also methods that are triggered
when a servlet is coded to explicitly unbind an attribute from a session, due to a
session being invalidated, or due to a session timeout. See "Event Listeners,"
earlier in this chapter.
5:What are the events that are defined for sessions?
A5: The primary events defined for sessions are session creation and destruction, and
when an attribute is added, changed, or removed from a session. The listener
interface monitors these events and calls associated methods. See "Event
Listeners."
Exam Questions
1:Which of the following two methods are used to track or store the session ID?
A. encodeURL()
B. sessionTrack()
C. sessionUpdate()
D. encodeRedirectURL()
A1: A and D. You append the session ID in URLs by calling the response's
encodeURL(URL) (or encodeRedirectURL()) method on all URLs returned by a
servlet. This method includes the session ID in the URL only if cookies are
disabled; otherwise, it returns the URL unchanged. See "Session Tracking
Through a URL Rather Than a Cookie," earlier in this chapter.
2:How do you create a session?
A. createSession()
B. makeSession()
C. callSession()
D. getSession()
A2: D. To get the current session in a servlet, you call the getSession() method of
HttpServletRequest. You have one parameter to think about. If you don't
provide a boolean, this method will create a session if one doesn't exist. The
same behavior occurs when you provide a true boolean. However, the container
will not create a new session if it doesn't already exist when you use a false
argument. See "Storing and Retrieving Session Objects," earlier in this chapter.
3:How do you retrieve a session object across multiple requests to the same or
different servlets within the same WebApp?
A. retrieveSession()
B. findSession()
C. getSession()
D. callSession()
A3: C. This is the same question as #2, but stated differently. You call the
getSession() method of HttpServletRequest to create a session. See "Storing
and Retrieving Session Objects," earlier in this chapter.
4:How do you store objects into a session object?
A. put(String, Object)
B. setAttribute(String, Object)
C. addObject(Object)
D. putObject(String, Object)
A4: B. You use the setAttribute(java.lang.String name, java.lang.Object
value) method to add objects to a session. The other methods listed are fake.
See "Storing and Retrieving Session Objects," earlier in this chapter.
5:How do you know if a session is alive?
B. getSession(false)
C. isSessionAlive()
D. Exception thrown if you try to create one when one already exists.
A5: B. This is somewhat difficult. You use getSession(false) method and test for a
null result.
HttpSession session = request.getSession(false);
if (session = null) {
//do something about lacking a session
}
If you get a null then the session is alive. You can also check for the session ID
with getId(), which returns the id of the session as a String representing the
unique identifier assigned to this session. If the session is dead, it will return a
null. See "Storing and Retrieving Session Objects," earlier in this chapter.
6:How do you destroy or expunge a session?
A. Session.isAlive = false;
B. Session.isNew(false)
C. invalidate()
D. removeSession()
A6: C. Only the invalidate() method can destroy a session. Notice that the session
can't be referenced after this method has been called. A and D are fake and B
isn't used properly. See "Storing and Retrieving Session Objects," earlier in this
chapter.
7:How do you know when a particular object is added to a session?
A. getCreationTime()
B. getAttribute(Date)
C. Session.attributeDate(index)
D. attributeAdded(HttpSessionBindingEvent)
A7: D. The attributeAdded(HttpSessionBindingEvent se) method gets called as
the notification that an attribute has been added to a session. The other options
are fake. See "Storing and Retrieving Session Objects," earlier in this chapter.
8:How do you know when a session is created?
A. sessionDidActivate(HttpSessionEvent)
A. sessionBound(HttpSessionEvent)
B. sessionFinalize(HttpSessionEvent)
C. sessionWillPassivate(HttpSessionEvent)
D. valueBound(HttpSessionEvent)
A9: C. The sessionWillPassivate(HttpSessionEvent) method is called as the
notification that the session is about to be passivated. This is strange language
so don't feel bad. They should have used another term such as alive or destroy.
A and B are fake. D (valueBound(HttpSessionBindingEvent)) is the
notification to the object that it is being bound to a session, but doesn't tell you
about the session being destroyed. See "Invalidating Sessions," earlier in this
chapter.
10:Given that URL-rewriting must be used for session management, identify the
query string attribute used when URL-rewriting.
A. sessionid
B. servletid
C. jsessionid
D. containerid
A10: C. The jsessionid is the parameter that is appended to URLs by the
encodeURL() method when cookies are not available to maintain state. The other
options are fake. See "Session Tracking Through a URL Rather Than a Cookie,"
earlier in this chapter.
11:Where are cookies stored?
A. On the server.
B. In web.xml.
C. On the client.
D. In HTML.
A11: C. Cookies are stored on the client only. See "Sharing State Information Between
Requests," earlier in this chapter.
12:Where are session IDs stored?
A. In cookies.
C. In query strings.
A. deleteAttribute(String)
B. attributeRemove(String)
C. removeAttribute(String)
D. setAttribute(null)
A13: C. The removeAttribute(java.lang.String name) method removes an
attribute. It deletes it from the session object. The other options are fake. See
"Using Session Objects," earlier in this chapter.
14:How do you get the date stamp of the session's creation?
A. getCreationTime()
B. sessionDate()
C. getSession(Date)
3. Exam objectives for the Sun Certified Web Component Developer for J2EE
Platform— http://suned.sun.com/US/certification/java/exam_objectives.html.
4. The Java Servlet 2.3 Specification—
http://jcp.org/aboutJava/communityprocess/first/jsr053/index.html.
This chapter covers the following Sun-specified objectives for Section 8—The
JavaServer Pages (JSP) Technology Model of the Sun Certified Web Component
Developer for J2EE Platform exam:
8.1 Write the opening and closing tags for the standard JSP tag types.
• Directive
• Declaration
• Scriptlet
• Expression
• JSP elements let you insert Java code into an otherwise standard Web page.
The server will use the opening and closing JSP tags (similar to, but not
exactly XML) to generate, and compile, a servlet. This servlet is a small
application like any other except that it waits for a call by the Web server and
its output is returned to the same server.
• The first time a JSP is invoked, the server translates the JSP page into servlet
code and then compiles it into a servlet, which is then loaded into memory. If
the JSP file is changed then the container repeats the translation and
compilation. The JSP tags tell the server which parts of the page contain Java
code and which parts contain HTML or other markup that should simply be
passed through to the browser. The plain text is compiled as quoted strings.
This section of the chapter focuses on the syntax rather then the details of
each element type, which are covered later in the chapter.
8.2 Given a type of JSP tag, identify correct statements about its purpose or
use.
• There are several distinct types of JSP tags. You will learn the purpose of
each. This section of the exam will test your understanding of what each type
of tag is used for.
8.3 Given a JSP tag type, identify the equivalent XML-based tags.
• The JSP technology has matured to read JSP tags in two forms. The syntax
for a scriptlet is <% yourCode %>, very similar to Microsoft's ASP. However,
another, I think better, form is XML-like, but not exactly. You can also use the
XML equivalent (real XML) such as
<jsp:scriptlet>yourCode</jsp:scriptlet>. This part of the exam focuses
on these XML equivalencies.
8.4 Identify the page directive attribute, and its values that:
• The page directive is how you tell the servlet engine to treat the entire JSP
page. The scope of this directive's attributes are page-wide, thus its name. It
defines attributes that apply to the entire JSP page. You use this tag to do
things like import classes, define buffer size, and identify an error page.
Although there are only four specific page directives named in the test
objective, we recommend you study all of them.
8.5 Identify and put in sequence the elements of the JSP page lifecycle.
• Page translation
• Load class
• Create instance
• Call jspInit
• Call jspService
• Call jspDestroy
• Each page has a lifecycle within the servlet engine. You will be required to
understand each step of the cycle and know the order of the steps.
8.6 Match correct descriptions about purpose, function, or use with any of
the following implicit objects.
• request
• response
• out
• session
• config
• application
• page
• pageContext
• exception
8.7 Distinguish correct and incorrect scriptlet code for Java statements.
• A conditional statement
• An iteration statement
• This section of the exam tests your ability to understand Java syntax. It is
less about JSP and more about Java syntax. This objective is about how to
properly delimit template text with complex scriptlet code, such as iterations
and conditionals. It is a common error to place the curly-braces in the wrong
place or to leave them out completely.
• This section of the exam covers how to perform a server-side include in a JSP
page. Please see the section on the include directive below. It discusses both
the include directive (<%@ include...> represents a static include) and the
include action (<jsp:include...> represents a dynamic include).
OUTLINE
Introduction
Directive
include Directive
taglib Directive
page Directive
Declaration
Scriptlet
Expression
Importing Classes
language
extends
buffer
autoFlush
isThreadSafe
info
contentType
request
response
session
config
application
pageContext
page
out
JSP Scriptlets
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• The key to this section of the exam is understanding the JSP syntax (plain
Java inside tags) and the lifecycle (JSP is compiled into a servlet). Don't be
thrown by servlets: They are classes that satisfy a specific functional interface
for operating on a Web server.
• There are several tags to know. Make sure you learn the basic tags and their
XML equivalents. The XML is easy, as the tag names make sense, like
<jsp:scriptlet> for scriptlets. Scriptlets are Java code sections delimited in
JSP so that the container knows to treat the section as Java code rather than
plain text.
• If you know Java, JSP is easy. The difference between the two has to do with
making Java play nicely within a Web page. The interface between Java and
the Web server is the tag set.
Introduction
JSP and servlets have greatly enhanced the way in which you can create and manage
Web pages with Java. The difficulty level of JSP is between HTML and pure Java. For
simple tasks like displaying the current date, you write a normal HTML page and add
only a small amount of Java as a scriptlet. For big tasks like processing a shopping
cart, you use JSP as the mediator between the Web form and a component (bean or
servlet) that has all the horsepower.
CGI had its day. Almost immediately after HTML became the Web's lingua franca,
programmers were meddling. CGI, Perl, and their cousins gave Web content dynamic
capability, an obvious evolution. However, using them to go beyond text processing
and simple database queries involves error-prone complexities. Microsoft Active
Server Pages (ASP) was the first Web server scripting champion. Tightly integrated
with the Windows operating system, ASP is the most widely used Web server
language, and to great effect. The Achilles' heel is its Windows-only attitude. A few
vendors have stepped in, providing ASP engines for the major non-Windows
platforms. I like ASP, but it isn't portable, object-oriented, or designed for building
enterprise class server applications. Notice, while porting the scripting part of ASP to
other platforms is easy, porting the COM/COM+ objects is almost impossible. This is
a big advantage of JSP: Not only does JSP run on all major platforms, but the
JavaBeans used by these JSPs run on all major platforms as well.
JSP competes directly with ASP. In fact, you would be forgiven if you thought it was a
copy. Sun took the same approach to JSP as it did with Java. Sun borrowed the
syntax of its best competitor (ASP for JSP and C++ for Java) with tweaks, but built
everything under the hood from scratch. Java syntax comes from C++, but it works
on all platforms with no portability migraines for the developer. JSP structure comes
from ASP (for example, ASP was the first popular scripting platform to use <% %> to
mark code and now JSP does, too). The look and feel, and some syntax, is the same.
However, ASP primarily uses Microsoft's versatile VBScript, while JSP uses the more
powerful and portable Java.
While it helps to know JSP's history, I won't say more about it. Let's focus on the
exam objectives. Let us start with a sample JSP page as follows:
It is often helpful to look at a snapshot of the syntax before exploring the topics of a
language. Shown in Table 7.1 is a snapshot of JSP syntax used in this chapter and on
the exam:
HTML Comment <!-- comment --> <!-- This HTML comment is passed
through to the client -->
if ( password == null)
{
%>
Password is required, thank you.
<%
} else
{
%>
Welcome to the member's area.
<%
}
%>
Table 7.1. JSP Syntax Snapshot
• Directive
• Declaration
• Scriptlet
• Expression
The intent behind this objective is making sure you are familiar with the syntax of
opening and closing the primary tags in JSP. The following discussion demonstrates
all the syntax you need to know for the exam.
One type of code that is not mentioned in the objectives, but for which examples
appear on the exam, is comments. Just so you don't get confused by them, please
review the two ways of commenting code.
Directive
Directives are a communication link between the JSP page and the JSP container.
Directives have this syntax:
<%@ directive { attr="value" }* %>
Directives are not used to display text; they don't contribute anything into the
current output stream. There are three directives: include, page, and taglib. Each
directive has several attributes that affect how the container processes the page.
include Directive
9.1 Given a description of required functionality, identify the JSP page
directive or standard tag in the correct format with the correct attributes
required to specify the inclusion of a Web component into the JSP page.
The first code listing could have been constructed as follows with the same result:
<html>
<head>
<title>QueQue Java Training Guide - JSP Example</title>
</head>
<body>
<center>
<h1><a href="http://www.que.com">QUE</a>
<br>Random Number Generator</h1>
<b>Que presents the following random numbers:</b>
<hr></hr>
<!--the code for generating and listing random numbers-->
<%@ include file="random_number_java.inc" %>
</center>
</body>
</html>
The random_number_java.inc file would look like this:
<!--text from random_number_java.inc-->
<%
StringBuffer html = new StringBuffer();
html.append("<ol type=\"I\">");
java.util.Random randomInt = new java.util.Random();
int limit = 10;
for (int count=0; count<limit; count++)
{
html.append("<li>" + randomInt.nextInt() + "</li>");
}
html.append("</ol>");
out.println( html.toString() );
%>
taglib Directive
The basic syntax of the taglib directive is as follows:
<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>
JSP technology makes it easy to embed Java code and functionality into HTML
documents. However, the author has to know Java to use scriptlets. This is true for
JavaBeans as well. You can use custom tags through the tag library facility. You can
embed functionality into JSP pages with easy-to-use custom tags that look like XML
or HTML. With custom tags, you are better able to separate presentation from
business logic.
Chapter 8, "Extend JSP with JavaBeans," discusses the tag library feature of JSP at
length. A taglib is a mechanism that enables you to specify your own custom tags.
JSP custom tags are merely Java classes with a special interface that makes it easy
to access them from a JSP page.
You start by writing a class that implements the Tag interface like so:
public class MyTag implements Tag { }
You code the methods of the Tag interface, including setPageContext, doStartTag
and doEndTag. The JSP container knows how to map the tag in the JSP to your
custom MyTag class, where you encapsulate your functionality. Then you create a Tag
Library Descriptor (TLD) that tells the JSP container about your tag library. Finally,
you use your tags in the JSP page by first including the taglib directive, then using
the actual tags like so:
<%@ taglib uri="/WEB-INF/jsp/myTaglib.tld" prefix="myTag" %>
...
<body>
myTag produces: <myTag:myMethod/>
page Directive
The page directive gives directions to the servlet engine about the general setup of
the page. This directive is covered in detail later in this chapter.
Declaration
In Java you must declare a variable before you use it. Largely, you type Java the
same in a JSP page, except for the delimiters. The syntax is nearly identical except
for delimeters and the expression (<%=someCodeThatCreatesOutput%>). A
declaration declares one or more variables or methods. Once declared, you can use
them later in the JSP page. Also, the scope of these declarations can be either local
(for example, inside a block) or instance declaration (apply to the entire JSP page).
The syntax inside the delimiters is the same as Java, so you can declare any number
of variables or methods within one declaration and you end each statement with a
semicolon. Why would you want to use this when it seems that a standard scriptlet
opening/closing will do just the same? You would because it makes your intentions
more explicit.
Scriptlet
The scriptlet is a way to include Java code directly in the page. Aside from the
requirement for the delimiters (which tells the JSP engine where to separate Java
from HTML), it is regular Java. The following is a trivial example (assume
java.util.* has been imported):
<% if (Calendar.getInstance()
.get(Calendar.AM_PM) == Calendar.AM)
{%>
Time for breakfast!
<% } else
{ %>
Time for dinner!
<% } %>
Scriptlets have access to the entire Java API. They are very powerful. The test
questions about these will require you to know Java syntax.
Expression
The basic syntax of the expression element is as follows:
<%= your_expression %>
An expression element contains Java code that is evaluated, converted to a string,
and inserted into the output stream. Expressions are never terminated with a
semicolon, a break with normal Java convention. Notice that an expression must be
converted to a String. Internally, JSP replaces the expression element with a String
to append to the output stream. During translation, the expression text is placed in a
out.print(<expr>); statement when the container transforms the JSP page into a
servlet. Therefore, you can treat it as text, such as place it in the middle of an HTML
tag, or anywhere for that matter. For example, the following is how you could
dynamically set the color of a font with an expression:
<font color="<%= Color.getCurrentColor() %>">
Colored Text</font>
As another example, you could display the current date like so:
<%= (new java.util.Date()).toLocaleString() %>
This objective is intended to get you to shift your focus from just syntax to purpose.
This section does not address the objective, per se. To be able to identify the correct
use of the tags, you must understand them in broader context. If you read this
chapter thoroughly, you will understand all the tags that appear on the test in terms
of why and when to use them, not just how to use them.
JSP enables you to use two forms of certain tag types. Table 7.2 offers a quick
review of the XML equivalents you need to know.
Table 7.2. XML Equivalents for Certain JSP Tag Types
<jsp:expression>
Expression <%=expression%>
expression
</jsp:expression>
<jsp:scriptlet>
Scriptlet <% yourCode %>
yourCode
</jsp:scriptlet>
<jsp:declaration>
Declaration <%! yourCode %>
yourCode
</jsp:declaration>
<jsp:useBean>
Actions None (XML only)
<jsp:setProperty>
<jsp:getProperty>
<jsp:include>
<jsp:forward>
<jsp:plugin>
Table 7.3 provides a list of examples for the XML actions you can take in JSP using
the XML equivalents.
<jsp:plugin type=applet
Plugin <jsp:plugin>
code="Customer.class"
codebase="/html">
<jsp:params>
<jsp:param name="debt"
value="large" />
</jsp:params>
<jsp:fallback>
<p>Unable to load applet</p>
</jsp:fallback>
</jsp:plugin>
Let's contrast two code snippets that result in the same output. The first is regular
JSP syntax:
<%@ page language="java" %>
<%=customerCount%>
The second snippet generates the same results as the previous snippet using the
XML equivalent:
<jsp:directive.page language="java"/>
<jsp:expression>customerCount</jsp:expression>
The page directive defines a page-dependent property (such as buffer size, location
of an error page) used by the JSP container. For example
<%@ page page_directive_attr_list %>
<%@ page info="Customer Support Page" %>
A JSP page, and any files included via the include directive, can contain one or more
page directives but no duplicates (the same attribute appearing more than once on a
page). The JSP container will apply all the attributes to the page. The position of
these page directives is irrelevant, but it is good practice to keep them together at
the top of the page.
While you can't duplicate any of the other attributes (which would result in a fatal
translation error), you can make multiple uses of the import attribute, the only
exception to the no-duplicate rule.
Importing Classes
Like in normal Java, you import classes to gain access to them. These imports are
cumulative, both in Java and JSP. The import attribute of the page directive is how
you import Java classes into a JSP page. The following is an example of how you
would import several packages:
<%@ page import="java.io.*,java.util.*,com.myCompany.*" %>
You can use many page directives or just one with a comma separated list of
packages or classes as the value of the import attribute. Like an import declaration
in the Java programming language, the value is either a fully qualified type name or
a package name followed by the ".*" string, denoting all the public types declared in
that package.
WARNING
Using autoFlush If autoFlush="true" and the contents of the initial JspWriter have
been flushed to the ServletResponse output stream, any subsequent attempt to
dispatch an uncaught exception from the offending page to an errorPage may fail.
When an error page is also indicated in the web.xml descriptor, the JSP error page
applies first, then the web.xml page.
The throwable object is transferred from the JSP page that generates it to the error
page. Internally, it does this by saving the object reference on the common
ServletRequest object using the setAttribute() method, with a name of
"javax.servlet.jsp.jspException".
language
The language attribute defines the scripting language to be used in the scriptlets,
expression scriptlets, and declarations. It looks like this:
<%@ page language="java" %>
Notice that this declaration also applies to any files included using the include
directive. In JSP 1.2, the value for this attribute is "java" and cannot be anything
else. The idea is that Servlet Container vendors will one day allow other languages
such as JavaScript, VBScript, Perl (Practical Extraction and Report Language), or
C++.
extends
The extends attribute works just like it does in regular Java. It allows you to inherit
a class by naming the superclass of the class created by runtime compiling this JSP
page. It looks like this:
<%@ page extends="package.class" %>
Be careful about using this attribute. Use this one sparingly because it allows the
developer to circumvent the JSP engine.
buffer
This attribute tells the JSP container how much space to allocate for the initial buffer
("out", which is the JspWriter). The syntax is
<%@ page buffer="16kb" %>
You should note that when the buffer is full, it writes the content in the buffer to the
output stream. If this attribute is set to "none", all output is written directly to the
output stream (ServletResponse PrintWriter). The size is set in kilobytes (the
suffix "KB" is required). If this attribute is not explicitly set, the page starts with a
default size of 8KB.
autoFlush
The autoFlush attribute tells the JSP container whether the buffered output should
be flushed. It is used thusly:
<%@ page autoFlush="true" %>
WARNING
Do Not Set autoFlush to "false" When the Buffer Is Set to None! It is illegal to
set autoFlush to "false" when the buffer is set to none. Also, if autoFlush is
"true" and the buffer gets flushed, any subsequent uncaught exception will likely fail
to return the specified errorPage reference.
When it is set to "true", the container automatically sends the contents of the buffer
to the output stream when the buffer becomes full.
The default setting is "true". You would want to set this to "false" if you wanted to
raise an exception to indicate a buffer overflow condition.
isThreadSafe
The info attribute stores an arbitrary string that can subsequently be retrieved with
the Servlet.getServletInfo() method. It is used like so:
<%@ page info="myPageInfo" %>
contentType
The contentType attribute tells the browser what kind of page it is. This attribute
specifies the MIME type of the page's output. The output type is included in the HTTP
header prior to data being printed to the client. The syntax is
<%@ page contentType="text/html; charset=ISO-8859-1" %>
The default is text ("text/html"), but you can specify many other types. Table 7.4 is
a short list of common page types:
Value Description
You cannot use MIME types that are binary format (like GZIP) as these cannot be
constructed in a JSP file. For a full list of MIME types, please see
http://www.oac.uci.edu/indiv/ehood/MIME/MIME.html. Also, look at the web.xml file
in CATALINA_HOME/conf/web.xml for the MIME types that all Web applications will
use. The following is a snippet declaring two MIME types for the jpeg image file:
<mime-mapping>
<extension>jpeg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
<mime-mapping>
<extension>jpg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>
NOTE
Notice! If you use Tomcat as recommended in this book, notice that Tomcat's
JspCServletContext (org.apache.jasper.servlet.JspCServletContext) is a simple
ServletContext implementation without HTTP-specific methods. In this class, you
can call getMimeType() to return the MIME type for the specified filename. Also, you
can add MIME types to Tomcat through the <mime-mapping> tag in the web.xml
configuration file as explained in the Tomcat documentation. The getMimeType
method is part of the SerlvetContext interface; therefore, it is a generic
mechanism; it is not unique to Tomcat.
The charset defines the character encoding. The JSP container applies this encoding
for the JSP page and for the response of the JSP page.
• Page translation
• Load class
• Create instance
• Call jspInit
• Call jspService
• Call jspDestroy
The JSP page lifecycle is on the exam. A JSP's life starts when it is first requested.
The Servlet Container (which does double duty by handling both JSP and servlets)
parses the JSP, creates a servlet, runs the servlet, handles responding to the
request, and manages servlet persistence. Smart containers place the servlet in
memory only once upon the first request to speed up processing. Table 7.5 offers a
quick review of the JSP page lifecycle you need to know.
Load class Loads the JSP page's servlet class upon first request.
Call jspInit Initializes the servlet instance by calling the jspInit method.
Call jspDestroy If the container needs to remove the JSP page's servlet, it calls the
jspDestroy method.
A JSP page is always converted to a servlet. Therefore the lifecycle of a JSP page is
largely determined by how the JSP container handles Java servlets.
Each JSP page is eventually converted to a servlet class and then compiled. Each
time a request is sent to a JSP page, the container compares the file dates. If the
JSP is younger than the servlet, the container recompiles it and then sends the
request to the servlet. The compiling process is performed automatically when the
server receives a request for that page.
There are two phases of a JSP page's life: translation and execution. In the
translation phase, the container starts building the final page, adding contents from
any includes and skipping JSP comments (but retaining HTML comments). The
container interprets all the Java code, such as directives, actions, and the custom
actions referencing tag libraries that occur in the page. Once this is done, the
container compiles the result into a servlet class. This completes the translation
phase and the servlet is ready to receive requests.
The execution phase involves instantiating request and response objects and
invoking the correct servlet based on the request. After the servlet finishes its work,
it hands the response object to the container. The container then sends the response
back to the client.
WARNING
The JSP Remains a Static Page Until Requested! The translation and compilation
phases can yield errors that are seen only when the page is requested for the first
time.
There are many types of elements in a JSP page, and each is processed differently.
The plain text (non-Java) is called template data and is simply passed through by
adding it to the output stream for the client. The directives and scripting elements
are inserted into the eventual servlet class.
• request
• response
• out
• session
• config
• application
• page
• pageContext
• exception
To simplify code in JSP expressions and scriptlets, you are supplied with eight
automatically defined variables, sometimes called implicit objects. The available
variables are request, response, out, session, application, config,
pageContext, and page. Details for each are given in the following sections.
request
This is the HttpServletRequest class instance associated with the client request.
The client sends a request message to the Web server. This object enables you to
inspect that request message. There is a surprising amount of information stored in
it. For example, you get the request type (GET, POST, and HEAD) and the associated
cookies. You can extract information from the request object and act on that data.
The following code listing shows you the various methods of the request object:
<html>
<body>
<h1> Inspecting the Request Object </h1>
<font size="4">
Request Method: <%= request.getMethod() %><br>
Request URI: <%= request.getRequestURI() %><br>
Request Protocol: <%= request.getProtocol() %><br>
Servlet path: <%= request.getServletPath() %><br>
Path info: <%= request.getPathInfo() %><br>
Path translated: <%= request.getPathTranslated() %><br>
Query string: <%= request.getQueryString() %><br>
Content length: <%= request.getContentLength() %><br>
Content type: <%= request.getContentType() %><br>
Server name: <%= request.getServerName() %><br>
Server port: <%= request.getServerPort() %><br>
Remote user: <%= request.getRemoteUser() %><br>
Remote address: <%= request.getRemoteAddr() %><br>
Remote host: <%= request.getRemoteHost() %><br>
Authorization type: <%= request.getAuthType() %><br>
Browser type: <%= request.getHeader("User-Agent") %>
</font>
</body>
</html>
Figure 7.2 shows the result of running the previous listing.
Figure 7.2. Walking through the request objects parameters
dynamically.
response
response.setContentType("text/html")
This is the HttpServletResponse class that manages the response to the client. You
use this object to send data back to the client. For example, among other things, you
can add cookies (addCookie), add a specified header (addHeader), and return an
error that includes a status and a default message (sendError). You can redirect a
browser to another URL with sendRedirect. You can set the content type and the
HTTP status (setStatus) as well.
The response object doesn't do much. Besides manipulating the output buffer (such
as, setBufferSize(), flushBuffer(), and getBufferSize()), Sun's public
interface ServletResponse defines only the following methods: getLocale(),
getOutputStream(), getWriter(), isCommitted(), setContentLength(),
setContentType(), and setLocale().
session
This is the HttpSession object associated with the request. The JSP container
handles (creates, tracks, and destroys) sessions automatically. You can use the
session attribute of the page directive to turn sessions off. When off, there is no
session state for a given JSP page, and any reference to the session variable causes
a fatal error.
The primary use of the session variable is to store state information between pages
for a given user. A session applies to a single user where you can share information
across JSP pages. This differs from the application object, which shares information
across all users. The session is on by default, so you don't have to set the
"session=true" attribute in the JSP page directive, but it is good practice to make
your intentions clear.
The exam objectives only address your understanding of what a session is and how
to turn on session tracking for a JSP page. Still, you should at least review the
methods and properties of the session object, as they might appear in a test
question. They are as follows (deprecated ones have been removed):
• getAttribute
• getAttributeNames
• getCreationTime
• getId
• getLastAccessedTime
• getMaxInactiveInterval
• invalidate
• isNew
• putValue
• removeAttribute
• setAttribute
• setMaxInactiveInterval
<%
String firstname = request.getParameter("firstname");
String lastname = request.getParameter("lastname");
String address = request.getParameter("address");
String city = request.getParameter("city");
String state = request.getParameter("state");
String zip = request.getParameter("zip");
session.setAttribute("firstname", firstname);
session.setAttribute("lastname", lastname);
session.setAttribute("address", address);
session.setAttribute("city", city);
session.setAttribute("state", state);
session.setAttribute("zip", zip);
%>
</body>
</html>
IN THE FIELD: SESSION AUTOMATICALLY MANAGED
Each new session gets its own unique id number. That is how the JSP
container keeps track of browsers. The number has to be long enough to
eliminate the possibility of session id collision. Please see Chapter 6, "Session
Management," for more on this.
config
application
While a session object shares information between JSP pages for a given user, an
application object shares information among all users of a currently active JSP
application. You can also use this object to communicate with the Servlet Container
running the current JSP page. Normally, there is one application object per Java
Virtual Machine. So, every JSP page on a Web server shares the same application
object.
When we need to store information for use throughout an application, we can store it
in the Servlet context, which is used to store the state for an entire Web application.
This is sometimes referred to as the application object. In JavaServer pages, the
implicit application object represents the Servlet context. Notice that unlike a
session object, the Servlet context is not invalidated by any updates or recompiling
of a given JSP page, or servlet for that matter. Whatever information you store in the
Servlet context will remain until the Web application itself is invalidated.
Be careful when you use the application or session objects. When your JSP page
is translated, depending on the vendor's implementation, the resulting servlet
declares certain objects internally. It is easy to cause an error. For example, Tomcat
translates most JSP pages into a servlet and places the code into the _jspService
method. The following objects are declared in that process:
//in public void _jspService(...
{
//...
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
//...
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
//...
Therefore, you shouldn't, and don't need to, declare a session object. Use session.
If you do declare your own, you can't use the names shown previously or you'll get
an error. If you write a servlet, and want to get the Servlet context, call the
getServletContext() method from inside the doGet() or doPost() method. This
method returns the javax.servlet.http.ServletContext instance that is
associated with this Web application.
Beyond sharing information among client requests, the application object provides
information about the environment of the JSP page. It also has methods for writing
messages to the server log.
A few of the methods and properties for the application are very similar to those of
the session object. The primary difference is scope, whether the objects are shared
only between pages being viewed by a single user (session) or all users (application).
The methods and properties include the following:
• getAttribute
• getAttributeNames
• getMajorVersion/getMinorVersion
• getMimeType
• getRealPath
• getResource
• getServerInfo
• log
• removeAttribute
• setAttribute
The following code listing demonstrates how to use the application object:
<html>
<head>
<title>Que Java Training Guide - JSP Example</title>
</head>
<body>
<center>
<h1><a href="http://www.quepublishing.com\">QUE</a>
<br>Application Object</h1>
<b>The application object has the following attributes:</b>
<hr></hr>
<%
String requestedURI = request.getRequestURI() ;
String filePath = application.getRealPath(requestedURI) ;
String serverInfo = application.getServerInfo() ;
int majorVersion = application.getMajorVersion() ;
int minorVersion = application.getMinorVersion() ;
StringBuffer html = new StringBuffer();
html.append("<ol type=\"A\">");
html.append("<li>" + requestedURI + "</li>");
html.append("<li>" + filePath + "</li>");
html.append("<li>" + serverInfo + "</li>");
html.append("<li>Major Version = "+ majorVersion +"</li>");
html.append("<li>Minor Version = "+ minorVersion +"</li>");
html.append("</ol>");
out.println( html.toString() );
%>
</center>
</body>
</html>
The above code listing produces the screen in Figure 7.3 on the author's machine.
Figure 7.3. You can use the application object to share data
between users and to get information about the JSP container.
pageContext
JSP has a class called pageContext. This is used in servlets to encapsulate server-
specific features. The following is a sample use:
HttpSession session = pageContext.getSession();
JspWriter out = pageContext.getOut();
The advantage is portability. The main goal of the pageContext is to encapsulate the
complete state of a single request-execution of a single JSP page. This object is
passed to custom actions so that these Java objects have access to anything that the
JSP page has access to.
page
In standard Java, the this keyword is a reference to the object for which the
instance method was invoked, or to the object being constructed (that is, using this
in a constructor). page is JSP's version of Java's this, but it isn't useful in JSP. The
JSP designers created it to address JSP's support for other scripting languages beside
Java. We recommend that you use the Java this keyword instead.
out
This is what the PrintWriter used to send output to the client. However, in order to
make the response object (see the "response" section earlier in this chapter) useful,
this is a buffered version of PrintWriter called JspWriter. Note that you can adjust
the buffer size, or even turn buffering off, through use of the buffer attribute of the
page directive. Also note that out is used almost exclusively in scriptlets, since JSP
expressions automatically get placed in the output stream, and thus rarely need to
refer to out explicitly.
WARNING
The clear method deletes all the content of the current buffer You have to be
very careful when using this method. Once the buffer has been flushed,
automatically or through code, calling clear throws an IOException error. Once data
is written to the client response stream, it is illegal to call the clear method.
The out variable is a Java PrintWriter you can use to write HTML to the browser
page from inside JSP tags. The following is an example of using the out object:
<%
out.clear(); //clears all output to the browser
out.print(out.getBufferSize()); //bytes available in Buffer
out.print("Hello Reader");
out.print( out.getRemaining() ); //bytes left in Buffer
out.newLine(); //prints a line return
out.flush(); //flushes the buffer
%>
JSP Scriptlets
8.7 Distinguish correct and incorrect scriptlet code for Java statements.
• A conditional statement
• An iteration statement
A JSP scriptlet is used to contain Java code fragments in a page. The following is an
example:
<html>
<body>
<%
java.util.Random randomInt = new java.util.Random();
int limit = 10;
%>
<ol type='i'>
<% for (int count=0; count<limit; count++) { %>
<li> <%=randomInt.nextInt()%> </li>
<% } %>
</ol>
</body>
</html>
In this example, the iteration construct begins on line 8 and ends on line 10.
However, if the developer left out line 10, then the iteration statement would not be
correctly structured.
The scripting language is normally Java. The point of this objective is to determine
whether the candidate understands how to structure scriptlet code around template
text (and other JSP code). This piece of code embedded in a page is transformed into
a Java programming language statement fragment by the compiler. It is then
inserted into the service method of the JSP page's servlet.
NOTE
Notice! Notice how all variables created within a scriptlet are accessible from the
appropriate scope, including anywhere within the JSP page if declared outside any
block.
<html>
<body>
<%
java.util.Random randomInt = new java.util.Random();
int limit = 10;
%>
<ol type='i'>
<% for (int count=0; count<limit; count++) { %>
<li> <%=randomInt.nextInt()%> </li>
<% } %>
</ol>
</body>
</html>
Chapter Summary
JSP is Java's way of making servlets easy to code while not losing any of the power
of server-side processing. JSP is a direct competitor to technologies like CGI, ASP,
ColdFusion, and PHP. A JSP page is comprised of several elements. This chapter
discusses all JSP elements and shows you what you need to know to answer the
exam questions about them.
KEY TERMS
• JSP
• servlet
• directive
• expression
• scriptlet
• implicit object
• JSP container
• tag library
• Web application
A1: JavaServer Pages is the Java 2 Platform, Enterprise Edition (J2EE) technology for
building applications for generating dynamic Web content, such as HTML, DHTML,
XHTML, and XML. The JavaServer Pages technology enables the easy authoring of
Web pages that create dynamic content with maximum power and flexibility. See
"Introduction."
2:What is the difference between JSP and servlets?
A2: JSP is the text page that provides a simple, yet powerful, way to add dynamic
data. The JSP is never run as-is when requested. It is compiled into a servlet. A
servlet is a special class with hooks for running on a Web server. See
"Introduction."
3:What is a Web application?
A3: A Web application is based on servlets. The specification defines a Web application
as being composed from
See "Introduction."
Exam Questions
1:Assume the custom tag is GLOOP and the prefix is TWONG. Which of the
following is the syntax for an empty custom tag?
A. <TWONG:GLOOP/>
B. <GLOOP:TWONG/>
C. <GLOOP:TWONG></GLOOP:TWONG>
D. <TWONG:GLOOP></TWONG:GLOOP>
A1: A, D. These use the correct syntax for an empty custom tag of GLOOP having the
prefix TWONG. See "Opening and Closing JSP Tags."
2:Which design pattern did the designers of JSP use to provide centralized
dispatching of requests via a controller servlet?
A. Model-View-Controller
B. Facade
C. Server-Client
D. Publish-Subscribe
A2: A. The Model-View-Controller design pattern is the one the designers of JSP use
to provide centralized dispatching of requests via a controller servlet. See
"Introduction."
3:Which of the following options is a valid declaration?
1 <html>
2 <head><title>Two Comments</title></head>
3 <body>
4 <%-- JSP Comment --%>
5 <!-- HTML Comment -->
6 </body>
7 </html>
Which option best describes what happens upon executing index.jsp?
<html>
<head>
<title>Retrieve Request Parameter</title>
</head>
<body>
<% String customerName =
request.getParameter("customer"); %>
<p>
The customer is <%=customerName %>
</body>
</html>
Assuming the www.que.com server is responding correctly and the page path is
valid, what displays in the browser if the user types
http://www.quepublishing.com/customer/request_parameter.jsp?customer=Devy
n?
A. The customer is
B. A blank page.
D. An error page.
A5: C. The declaration is correct. The customer is <%=customerName %> fragment
becomes The customer is Devyn. See "Declaration."
6:The following are the contents of welcomeHeader.inc:
A. An error occurs.
D. The page displays, but replaces the welcome header with the words
welcomeHeader.inc.
A6: A. The following is wrong: <%@ include file="file" %>. It should have been
<%@ include file="welcomeHeader.inc" %>. Note that "file" in quotes
literally means you were asking the system to include a file whose filename is
"file." See "include Directive."
7:Which of the following options is a JSP implicit object?
A. objRequest
B. Request.send
C. request
D. servlet
A7: C. Option C is correct if the request is the only implicit object. See "JSP Implicit
Objects."
8:Which of the following options is not a JSP implicit object?
A. out
B. in
C. response
D. page
A8: B. All of these are JSP implicit objects except the fictitious in. See "JSP Implicit
Objects."
9:Which of the following will not compile (assume <x:tag> is a valid custom tag
that is declared for the current JSP file)?
A. application
B. page
C. request
D. session
A10: A. The same application object is accessible by all users. See "JSP Implicit
Objects."
11:Which among the following objects is the best choice to share information
between pages for a single user?
A. application
B. page
C. request
D. session
A11: D. The session object is the best choice for sharing information between pages
for a single user. Users can see their own session object, but can't see others'
session objects. See "JSP Implicit Objects."
12:Which of the following objects is used to share information between pages using
the setAttribute and getAttribute methods?
A. application
B. page
C. request
D. session
A12: A, C, and D. Both the application and the session objects can be used to
share information between pages with the setAttribute and setAttribute
methods. Either A or D is correct. Option C is also valid because you can share
attributes from a "master" page to an "included" page. See "JSP Implicit
Objects."
13:Which option is a valid page directive?
17:Which of the following options is a valid XML equivalent to the include directive?
C. The plain text (such as HTML) outside JSP tags (non Java) in a JSP page.
A. Page translation, JSP page compilation, Load class, Create instance, Call
jspInit, Call jspDestroy, Call _jspService
B. Page translation, JSP page compilation, Load class, Create instance, Call
jspInit, Call _jspService, Call jspDestroy
C. JSP page compilation, Page translation, Load class, Create instance, Call
jspInit, Call _jspService, Call jspDestroy
D. Page translation, JSP page compilation, Create instance, Load class, Call
jspInit, Call _jspService, Call jspDestroy
A19: B. All the others have the correct steps, but they are in the wrong order. See
"JSP Page Lifecycle."
This chapter covers the following Sun-specified objectives for Section 10, "Designing
and Developing JSP pages Using JavaBean Components," of the Sun Certified Web
Component Developer For J2EE Platform exam:
10.1 For any of the following tag functions, match the correctly constructed
tag, with attributes and values as appropriate, with the corresponding
description of the tag's functionality:
• The useBean, getProperty, and setProperty standard tags are the bulk of
what you need to know for the exam regarding JavaBeans. These elements
are how you instantiate a Bean and get and set the Bean's properties.
10.2 Given JSP page attribute scopes: request, session, and application,
identify the equivalent servlet code.
• This objective is poorly worded. What Sun wants you to understand is that the
Bean has scope, just like all variables. What does the code look like when you
instantiate a Bean within a given scope, and then later refer to it in scriptlet
code? The practical value of JavaBeans is the capacity to use prebuilt
components and reusability. Sun's implementation also provides programmers
an elegant way to copy request form parameters directly into bean properties
without manual code. The essence of this chapter is an explanation of how
JavaBeans is a standard way to snap in modular functionality.
• How do you use a declared Bean in JSP code? This objective reflects the fact
that you need to be able to access Beans with both standard actions and
scriptlets.
OUTLINE
Introduction
Creating JavaBeans
jsp:useBean
jsp:setProperty Action
jsp:getProperty Action
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• The key to this section of the exam is understanding how JSP uses JavaBeans.
You need to know how to call JavaBeans from JSP. While writing JavaBeans is
not on the exam, knowing how to create them really helps you understand
this technology.
• There are few methods to know regarding JavaBeans on the exam, but you do
need to know the XML syntax for calling and using JavaBeans.
• While I will show you how to create JavaBeans, they are not on the exam
directly; only in terms of calling them from JSP. However, it is important to
know how that Sun defines them as a Java class that satisfies the following
requirements: a) the class contains a no-argument constructor, b) the class
uses standardized method names for property accessors and mutators, and c)
there are no public instance variables.
Introduction
Visual Basic became a sensation because of its plug-and-play development
capabilities. Visual Basic is a language, but Microsoft also used the same name to
refer to the IDE. The language itself was, and is, neither fast nor elegant. However,
Bill Gates knew that if he made it easy to use, programmers would adopt it as their
development tool, so he came up with a visual IDE that took the development
industry by storm. Microsoft combined QuickBasic with Alan Cooper's drag-and-drop
shell, resulting in the first tool that allowed programmers to quickly create Windows
applications. Thousands of programmers and newbies loved the visual drag-and-drop
programming model. VB attracted an unprecedented number of newbies. The old
guard was offended by all the new faces who knew nothing about the intricacies of
sophisticated software techniques. No matter, a flood of good and bad software
flowed from the VB community, which had a major impact on the whole software
industry. Mr. Gates' intuition about a plug-and-play IDE was proven right.
The original focus of JavaBeans was visual componentry. Like the original Visual
Basic IDE (now Visual Studio), you can drag and drop buttons and the like in an
Integrated Development Environment (such as JBuilder, VisualAge, and Café). These
IDEs use components that are JavaBeans. Don't confuse JavaBeans that are used for
visual components like buttons and textboxes (for standalone executable
development) with JavaBeans that used for JSP (for Web applications). Sun provides
a BeanBox which makes it easy to construct visual-type JavaBeans components.
Presently, Sun has the Bean Builder
(java.sun.com/products/javabeans/beanbuilder/index.html), which helps you
construct applications using JavaBeans.
The Bean Builder extends the capabilities of the original BeanBox. These JavaBeans
are not part of the exam. The JavaBeans that are used with JSP are invisible to the
user and are meant to act as state machines.
While it is not part of the exam, you might look at the JavaBeans Development Kit
(BDK), which can help you develop JavaBeans components. The BDK has a Bean
container called the "BeanBox," a variety of sample Beans, and a tutorial explaining
the main JavaBeans 1.0 concepts using the BeanBox
(java.sun.com/products/javabeans/software/bdk_download.html). The BeanBox is
not designed to help you build JavaBeans for JSP. It is a visual component builder for
GUI work. However, it is a decent tool otherwise.
Let me give you one example of how you could use EJB. Imagine you have a
database of marketing data that different departments in your company need access
to. Rather than allow these departments to write their own code that talks to the
database (which would have security implications and would cause problems anytime
you changed the database schema), you decide to give the departments JavaBeans
to use for the integration. The JavaBeans handle the business logic and the
departments write their own JSPs to handle the presentation logic. Here's the
gotcha: If you hand out the JavaBeans to 15 departments and later discover a bug
with them or change the database schema, you have to fix the beans and
redistribute updated beans to each department, where they must be installed
successfully. With EJB, the actual "bean" can live on your server. The departments
interface with the EJB through the remote and home interfaces, not with the EJB
directly. If you ever have to update the internal application logic of the EJB, or the
database schema changes, you won't have any problem unless a change in the
remote or home interface is necessitated.
JavaBeans and EJBs encapsulate the business logic of an application. Just remember
that the exam doesn't include EJBs, but does focus on JavaBeans.
The way Sun has designed JavaBeans for use in a JSP environment ignores much of
JavaBeans' original GUI focus. While it is possible to have a JSP IDE which represents
beans graphically, making visual components for presentation, the original JavaBeans
motivation is left out completely. The name indicates reusable components, so they
kept it along with the read/write (get/set method convention) properties and some of
the plumbing underneath. In JSP, we have a stripped down version of JavaBeans (no
GUI): This is what you'll see on the exam. However, JSP code can get unwieldy.
When the number of scriptlet lines exceeds 100, a JSP gets ugly and hard to
maintain. Of course, you could always use servlets. However, using beans is even
better because beans separate display and logic, whereas servlets tend to mix the
two. Sometimes, though, it is best to use a component that is good not only for JSP
but for many situations, such as for the GUI portion of a standalone application. Each
JavaBean component has the expected class structure, but follows a convention that
includes get and set methods. This convention is what transforms a regular class into
a JavaBean.
A JavaBean itself is ordinary. JavaBeans do not extend any specific class. Rather, the
container allows JSP to access classes, and this access, along with the JavaBean
convention of set/get methods, are the interesting features. A class becomes a
JavaBean if it is public, has a public constructor with no arguments, follows the
set/get paradigm, and is placed where the container can access it. Once you meet
these criteria you can take advantage of the JavaBean, sometimes called simply
Bean, by writing the XML tags in JSP that bring that Bean into play. It is more a
matter of how you use the class that makes a Bean rather than syntax or inheriting a
special class.
Before we dive into details, look at Figure 8.1, which illustrates how the container
processes a request to a JSP page that employs a JavaBean. This is a high-level
process diagram, but it gives a nice framework to see what is going on.
Let us start with a quick example. Listing 8.1 presents a small JavaBean. You can see
that there is nothing in the code itself to indicate that it is a Bean. What makes it a
Bean is how it is used by the application, not any keyword. Notice that there isn't
anything special about making a bean except the no-arg constructor and set/get
method nomenclature. Listing 8.1 demonstrates a JavaBean class.
package que.scwcd;
/**********************************************
* The attributes
*
*/
private String username = "";
private String password = "";
/**********************************************
* Get methods for the attributes
*
*/
public String getUsername()
{
return(username);
}
public String getPassword()
{
return(password);
}
/**********************************************
* Set methods for the attributes
*
*/
public void setUsername(String value)
{
username = value;
}
public void setPassword(String value)
{
password = value;
}
/**********************************************
* The validate method.
* Of course, you would implement something
* better, but this suffices to show
* you how the bean and JSP interact.
*/
public boolean confirmLogin()
{
boolean valid = true;
if (username.length() == 0 ||
password.length() == 0)
{
valid = false;
}
return(valid);
}
}
<%
if (security.confirmLogin())
{
%>
<jsp:forward page="welcome.jsp"/>
<%
}
%>
<html>
<head>
<title>JavaBean Example</title>
</head>
<body bgcolor="#FFFFFF">
<p />
<h1>JavaBean Example</h1>
<form method="POST" action="login.jsp">
<table>
<tr>
<td>
User name
</td>
<td>
<input name="username"
size=15 value="<%=security.getName()%>">
</td>
</tr>
<tr>
<td>
Password
</td>
<td>
<input type=password name="password" size=15>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value=" Login ">
</td>
</tr>
</table>
</form>
</center>
</body>
</html>
Listing 8.1 shows a JavaBean and JSP combination with only two attributes. The
username and password attributes are really private variables with class scope. You
also see the attributes' get and set methods. Lastly, you read a no args constructor.
These three things are all you need to have a JavaBean.
When you use jsp:useBean and specify the class, it must be in the correct class
path. This can be confusing. I've read various bogus pieces of advice on this. In
Tomcat on Windows, the servlets directory has the default path of
CATALINA_HOME\webapps\examples\WEB-INF\classes. You access servlets in this
directory with http://localhost:8080/examples/servlet/ (CATALINA_HOME refers
to the directory into which you have installed Tomcat). On my Windows machine, I
placed the class in CATALINA_HOME\webapps\examples\WEB-
INF\classes\que\scwcd\SmallBean.class. Notice that the package is que.scwcd.
To compile it you need to start in the classes directory with the command javac
que\scwcd\SmallBean.java. A bean class (like any other Java class in a Web app)
can be placed in either the WEB-INF/classes/ directory or in the WEB-INF/lib/
directory (if the class exists in a JAR file).
WARNING
Beans must belong to a Java package! Be careful about how the JSP compiler
places the generated servlet code into a package which reflects the source's directory
structure. The JSP translator puts the JSP page into its own package. If the
class/type attribute of a useBean refers to a class in the "default" package, the
compiler will try to find that class in the package of the JSP servlet classes. However,
the JavaBeans in your JSP can't be referenced by the generated servlet code unless
you place them in a package (a directory beneath the default class folder). You MUST
place your JavaBeans in a package or the servlet engine (such as Tomcat) will throw
an exception because it won't be able to find the JavaBean.
Let us now look at the JSP page that will use the JavaBean in Listing 8.1. Listing 8.2
uses the jsp:useBean element to declare a JavaBean. It then sets a property, of
which there is only one in this JavaBean. Finally, it gets the value of the same
property and adds that value to the output stream.
Listing 8.2 The Source Code for JSP That Uses jsp:useBean
(SmallBean)
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Using JavaBeans in JSP</TITLE>
</HEAD>
<BODY>
<CENTER>
<h1>Using JavaBeans in JSP</h1>
</CENTER>
<P>
<!--load your bean with useBean-->
<jsp:useBean id="lilFella" class="que.scwcd.SmallBean" />
<jsp:setProperty name="lilFella"
property="message"
value="Congratulations! You will pass the exam." />
<h3>Bean Attribute</h3>
<b>
<!--JSP engine replaces this next line with
the value of attribute in the bean
which has been set to "Congratulations..."
with the jsp:setProperty element above.-->
<jsp:getProperty name="lilFella" property="message" />
</b>
</BODY>
</HTML>
Listing 8.2 shows a JSP page that uses the jsp:useBean element. There is little
magic going on, with only one attribute set, then retrieved and displayed. That is all
you need to have a JavaBean. This file is called BeanInJSP.jsp and is in the directory
CATALINA_HOME\webapps\examples\jsp\que\scwcd\BeanInJSP.jsp. I called it
using: http://localhost:8080/examples/jsp/que/scwcd/BeanInJSP.jsp. Now, let
us see what HTML was generated.
Listing 8.3 shows the HTML generated by Listing 8.2. Again, this is all trivial code,
but you can easily follow the flow of what is going on that way.
Listing 8.3 The Source Code for JSP That Uses jsp:useBean
(SmallBean)
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Using JavaBeans in JSP</title>
</head>
<body>
<center>
<h1>Using JavaBeans in JSP</h1>
</center>
<p />
<!--load your bean with useBean-->
<h3>Bean Attribute</h3>
<b>
<!--JSP engine replaces this next line with
the value of attribute in the bean
which has been set to the "Congratulations..."
with the jsp:setProperty element above.
-->
Congratulations! You are closer to passing the exam.
</b>
</body>
</html>
Listing 8.3 shows the HTML produced by the previous listings. Notice that
CATALINA_HOME will be something like jakarta-tomcat-
4.0\work\standalone\localhost. The HTML in Listing 8.3 is rendered by a browser,
where it looks like Figure 8.2.
It is helpful to look at how Tomcat converted the JSP page in Listing 8.2 into a
servlet. Using JavaBeans is easy because the container is doing a lot of work for you.
You can see the file if you go to
CATALINA_HOME\work\localhost\examples\jsp\que\scwcd\BeanInJSP$jsp.java.
Of course, while each vendor's container will handle this somewhat differently, they
will all follow the specification concerning JavaBeans. Listing 8.4 shows you the code
Tomcat generated when it converted BeanInJSP.jsp into a servlet. Notice what it did
about the jsp:useBean element.
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
// begin [file="/jsp/que/scwcd/BeanInJSP.jsp"...
// end
static {
}
public BeanInJSP$jsp( ) {
}
if (_jspx_inited == false) {
synchronized (this) {
if (_jspx_inited == false) {
_jspx_init();
_jspx_inited = true;
}
}
}
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType(
"text/html;charset=ISO-8859-1");
pageContext = _jspxFactory.getPageContext(this,
request, response,
"", true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// end
// begin [file="/jsp/que/scwcd/BeanInJSP...
que.scwcd.SmallBean lilFella = null;
boolean _jspx_speciallilFella = false;
synchronized (pageContext) {
lilFella= (que.scwcd.SmallBean)
pageContext.getAttribute("lilFella",
PageContext.PAGE_SCOPE);
if ( lilFella == null ) {
_jspx_speciallilFella = true;
try {
lilFella = (que.scwcd.SmallBean)
java.beans.Beans.instantiate(
this.getClass()
.getClassLoader(),
"que.scwcd.SmallBean");
} catch (ClassNotFoundException exc)
{
throw new InstantiationException(
exc.getMessage());
} catch (Exception exc) {
throw new ServletException (
"Cannot create bean of class "+
"que.scwcd.SmallBean", exc);
}
pageContext.setAttribute("lilFella",
lilFella, PageContext.PAGE_SCOPE);
}
}
if(_jspx_speciallilFella == true) {
// end
// begin [file="/jsp/que/scwcd/BeanInJSP.jsp...
}
// end
// HTML // begin [file="/jsp/que/scwcd/BeanI...
out.write("\r\n");
// end
// begin [file="/jsp/que/scwcd/BeanInJSP.jsp...
JspRuntimeLibrary.introspecthelper(
pageContext.findAttribute("lilFella"),
"attribute","Congratulations! You will"+
" pass the exam.",null,null, false);
// end
// HTML // begin [file="/jsp/que/scwcd/BeanI...
out.write("\r\n \r\n<h3>Bean"+
" Attribute</h3> \r\n<b>\r\n<!--JSP engi"+
"ne replaces this next line with \r\n "+
" the value of attribute in the bean\r\n"+
" which has been set to the \"Congrat"+
"ulations...\" \r\n with the jsp:setP"+
"roperty element above.-->\r\n");
// end
// begin [file="/jsp/que/scwcd/BeanInJSP.jsp...
out.print(JspRuntimeLibrary.toString((((
que.scwcd.SmallBean)pageContext
.findAttribute("lilFella"))
.getAttribute())));
// end
// HTML // begin [file="/jsp/que/scwcd/BeanI...
out.write("\r\n</b>\r\n "+
" \r\n</BODY>\r\n</HTML>\r\n");
// end
} catch (Throwable t) {
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (pageContext != null)
pageContext.handlePageException(t);
} finally {
if (_jspxFactory != null)
_jspxFactory.releasePageContext(pageContext);
}
}
}
Clearly, a lot is happening. I apologize for the appearance; the code was edited to fit
on the page. Focus on the code that handles the jsp:useBean element. The first line
of interest is this:
pageContext.getAttribute("lilFella",PageContext.PAGE_SCOPE);
The above line creates an attribute with page scope. Then it instantiates the class
with this:
[View full width]
Next, the servlet replaces the jsp:getProperty action in JSP with the following
code:
[View full width]
out.print(JspRuntimeLibrary.toString((((que.scwcd.
SmallBean)pageContext.findAttribute(
"lilFella")).getAttribute())));
Now that we have walked through the entire process of using a JavaBean in JSP, we
need to discuss the specifics of the syntax which will be on the exam.
jsp:useBean
The jsp:useBean JSP element declares that a bean is stored within and accessible
from the specified scope (application, session, request, or page). It boils down to
creating an object which has get and set methods that are easy to use in JSP. Even if
you need only a simple object to hold values, and especially if you have to do more
than that (such as compute tax), I recommend you write a JavaBean.
When you use jsp:useBean, the container performs several actions. Basically, it
instantiates the object in memory and provides a variable name for you to use within
the scope you set in the tag. If the bean class hasn't been loaded, the container will
try to locate it and load it. The container creates the bean and stores it as an
attribute of the scope object. The value of the id attribute determines the name of
the bean within the object scope. Also, you use that name to refer to the object in
other JSP elements and scriptlets.
The syntax is
<jsp:useBean id="name"
scope="page|request|session|application" typeSpec />
typeSpec ::= class="className" |
class="className" type="typeName" |
type="typeName" class="className" |
beanName="beanName" type="typeName" |
type="typeName" beanName="beanName" |
type="typeName"
The id and scope are easy. The confusion arises over the typeSpec. The container
will always look for the Bean. However, if the typeSpec is used one way, the
container will throw an exception if it can't find that Bean (not already instantiated).
If it is used another way, it will create a new instance of the Bean if one hasn't been
created already.
WARNING
If the bean has been instantiated already, the body is not executed! The
Body portion of the jsp:useBean element is executed only when the bean is first
instantiated. If the bean instance has already been loaded into memory from a
previous jsp:useBean (for example, in the previous page with session scope) the
body of the jsp:useBean element will not be executed. Since beans can be shared,
jsp:useBean doesn't always newly instantiate a bean. The body is executed only
once for a given bean, regardless of how many jsp:useBean elements refer to it.
Also, you'll get an exception if more than one jsp:useBean refers to the same ID.
To get you started, Table 8.1 offers a quick overview of the useBean attributes.
Attribut Definition
e
id
The case sensitive name used to identify the object instance in the
specified scope. This name doubles as the scripting variable name
declared and initialized with that object reference.
scope The scope within which the reference is available. The default value is
page. The options are page, request, session, and application.
class The fully qualified name of the class. If the class and beanName
attributes are not specified the object must be present in the given
scope. The class must not be abstract (or an interface) and must have a
public, no-argument constructor, but the implicit no args constructor will
suffice.
type If specified, it defines the type of the variable defined. The type is
required to be the class itself, a superclass of the class, or an interface
implemented by the class specified. If unspecified, the value is the same
as the value of the class attribute.
Let's study an example. The following is a more complete JavaBean example. Listing
8.5 represents an address JavaBean. The combination of attribute and associated set
and get methods is here. Get and set methods are not required in JavaBeans.
setProperty and getProperty expect proper JavaBean mutator and accessor
method names. If you don't have these methods, you can still call other methods the
bean might have, but you can't use the setProperty and getProperty elements.
Listing 8.5 The Source Code for a Full JavaBean
/**
* AddressBean.java
*
* represents an address object including attributes
* and operations to encapsulate all the information
* necessary to contact an individual. You could make
* a contact object by extending this object and adding
* things like company, department, jobTitle...
*
* @version 1.0
* @author Alain Trottier
*/
package que.scwcd;
/* CLASS ATTRIBUTES */
String fullName;
String firstName;
String lastName;
String street;
String city;
String state;
String zip;
String country;
String phone;
String cell;
String pager;
String email;
String webPage;
String note;
/* CLASS METHOD */
return true;
/* GET METHODS */
/**
* Returns the fullName
* @return A String that represents the fullName.
*/
public String getFullName () {
return fullName;
}
/**
* Returns the firstName
* @return A String that represents the firstName.
*/
public String getFirstName () {
return firstName;
}
/**
* Returns the lastName
* @return A String that represents the lastName.
*/
public String getLastName () {
return lastName;
}
/**
* Returns the street
* @return A String that represents the street.
*/
public String getStreet () {
return street;
}
/**
* Returns the city
* @return A String that represents the city.
*/
public String getCity () {
return city;
}
/**
* Returns the state
* @return A String that represents the state.
*/
public String getState () {
return state;
}
/**
* Returns the zip
* @return A String that represents the zip.
*/
public String getZip () {
return zip;
}
/**
* Returns the country
* @return A String that represents the country.
*/
public String getCountry () {
return country;
}
/* SET METHODS */
/**
* Sets the value of fullName.
* @param fullName String
*/
public void setFullName (String theFullName) {
fullName = theFullName;
}
/**
* Sets the value of fullName.
* @param fullName String
*/
public void setFullName () {
fullName = firstName + " " + lastName;
}
/**
* Sets the value of firstName.
* @param firstName String
*/
public void setFirstName (String theFirstName) {
firstName = theFirstName;
}
/**
* Sets the value of lastName.
* @param lastName String
*/
public void setLastName (String theLastName) {
lastName = theLastName;
}
/**
* Sets the value of street.
* @param street String
*/
public void setStreet (String theStreet) {
street = theStreet;
}
/**
* Sets the value of city.
* @param city String
*/
public void setCity (String theCity) {
city = theCity;
}
/**
* Sets the value of state.
* @param state String
*/
public void setState (String theState) {
state = theState;
}
/**
* Sets the value of zip.
* @param zip String
*/
public void setZip (String theZip) {
zip = theZip;
}
/**
* Sets the value of country.
* @param country String
*/
public void setCountry (String theCountry) {
country = theCountry;
}
/**
* the get/set methods for phone, cell, pager,
* email, webpage and note have been
* omitted for space. They are present
* in the full source on the CD and Web site.
*/
}
Listing 8.5 showed you an example of a more useful JavaBean. Once the bean is
compiled, you can use it in a JSP-based Web page with this:
<jsp:useBean id="addressBean" scope="request"
class="que.scwcd.AddressBean">
This XML snippet is how you create an instance of the AddressBean class in the
container. Once you do that, the Bean is in memory, but the attributes are initially
null. To change these attributes, you can use scriptlets or XML. Generally, XML is
better than scriptlets, so try to stay with XML.
When you use jsp:useBean, the container performs several actions. Basically, it
instantiates the object in memory and provides a variable name for you to use within
the scope you specified in the tag. If this JavaBean doesn't actually exist, the
container will try to create it. The following actions are paraphrased from the
specification:
• Container declares a variable for the class with the same name as the id. It
has the same scope as declared in the tag.
• If the object is found, the variable's value is initialized with a reference to the
located object, cast to the specified type. If the cast fails, a
java.lang.ClassCastException shall occur. This ends the processing of this
jsp:useBean action.
• If the object is not found in the specified scope and neither class nor
beanName are given, a java.lang.InstantiationException shall occur. This ends
the processing of this jsp:useBean action.
• If the object is not found in the specified scope, and the class specified names
a non-abstract class that defines a public no-args constructor, the class is
instantiated. The new object reference is associated with the scripting variable
using the scope specified (see PageContext). After this, the last step listed
below is performed.
• If the object is not found, and the class is abstract, an interface, or no public
no-args constructor is defined, then a java.lang.InstantiationException shall
occur. This ends the processing of this jsp:useBean action.
• If the object is not found in the specified scope and beanName is given, then
the container attempts to create the bean. If it succeeds, the new object
reference is associated with the scripting variable in the specified scope.
You can see that the container does a lot of work for you so that you only need a few
tags to perform helpful work.
Ideally, the entire JSP page is in XML; that would be best. Presently, we will use
<jsp:setProperty> to change the attributes to the values from a set of fields from
an HTML form. There is less coding to do when the form field names match the
JavaBean property names. This is one of the main purposes of Beans, to make life
easier for the programmer. At least it makes certain steps more concise and less
prone to mistakes. Listing 8.6 shows the JSP that uses the AddressBean.
Listing 8.6 The Source Code for JSP That Uses jsp:useBean
(AddressBean)
<jsp:useBean id="addressBean" scope="request"
class="que.scwcd.AddressBean">
<!-- Set all the attributes at once with property="*".
Values come from the request object, previous post.
You could add attributes with jsp:setProperty setting:
property="attributeName" value="yourValue"
-->
<jsp:setProperty name="addressBean" property="*"/>
</jsp:useBean>
<!--
Demonstrates how to use Bean in scriptlet.
Make sure to use semicolon.
-->
<% addressBean.setFullName(); %>
<html>
<head>
<title>Provide Address Information</title>
</head>
<body>
<center>
<h1>Provide Address Information</h1>
<hr />
<!--
This is a silly thing to do, but it shows you how
to get values back out of a bean.
-->
First Name:<jsp:getProperty name="addressBean"
property="firstName" /><br />
Last Name:<jsp:getProperty name="addressBean"
property="lastName" /><br />
Full Name:<jsp:getProperty name="addressBean"
property="fullName" /><br />
Street:<jsp:getProperty name="addressBean"
property="street" /><br />
City:<jsp:getProperty name="addressBean"
property="city" /><br />
State:<jsp:getProperty name="addressBean"
property="state" /><br />
Zip Code:<jsp:getProperty name="addressBean"
property="zip" /><br />
Country:<jsp:getProperty name="addressBean"
property="country" /><br />
Phone:<jsp:getProperty name="addressBean"
property="phone" /><br />
Pager:<jsp:getProperty name="addressBean"
property="pager" /><br />
Cell:<jsp:getProperty name="addressBean"
property="cell" /><br />
Email:<jsp:getProperty name="addressBean"
property="email" /><br />
Web Page:<jsp:getProperty name="addressBean"
property="webPage" /><br />
Note:<jsp:getProperty name="addressBean"
property="note" />
</body>
</html>
Listing 8.6 shows you how to use the AddressBean in a JSP page. It produces ugly
HTML, but it serves as an instructive example.
jsp:setProperty Action
You use jsp:setProperty to set the properties values of beans that have been
referenced earlier in the JSP page. In Listing 8.5 you see several setProperty actions
for setting the JavaBean properties.
The next way to do this is a shortcut between the request object parameter and the
JavaBean property. You tell the container which parameter to take the value from
and which JavaBean property to assign that value to. The parameter name in the
request object doesn't have to match the property name in the JavaBean, but
making them the same makes your code cleaner. When using the jsp:setProperty
element, the container will take the parameter value and assign it to the JavaBean
property variable. You do that like so:
<jsp:setProperty name="addressBean" property="state" param="state" />
The property is the name of the attribute in the JavaBean, while the param is the
name of the parameter in the request object. Notice how the param attribute is
optional if it is the same as the property attribute. There is yet another shortcut. If
you look in Listing 8.5, you'll find the following element:
<jsp:setProperty name="addressBean" property="*"/>
You'll notice that the property is set to the wildcard star. That tells the container to
match as many request parameters with JavaBean properties as possible. With each
match, the container takes the value from the request object and places it in the
JavaBean property variable. Due to how the HTML form and JavaBean were
designed, only one tag was needed to accomplish transferring all the form field
values in Listing 8.5 to the JavaBean properties. Notice that the HTML field names
have to match exactly (that is, case-sensitively) with the JavaBean properties for this
elegant trick to work.
Table 8.2 offers a quick overview of the setProperty attributes. The definitions are
slightly edited from the specification.
Attribut Definition
e
property The name of the Bean property whose value you want to set. If you set
propertyName to *, the tag will iterate over the current ServletRequest
parameters, matching parameter names and value type(s) to property
names and setter method type(s), setting each matched property to the
value of the matching parameter. If a parameter has a value of "", the
corresponding property is not modified.
param The name of the request parameter (Web form or query string) whose
value you want to give to a Bean property. If you omit param, the request
parameter name is assumed to be the same as the Bean property name.
If the param is not set in the Request object, or if it has the value of "",
the jsp:setProperty element has no effect. An action may not have
both param and value attributes.
value The value to assign to the given property. This attribute can accept a
request-time attribute expression as a value. An action may not have
both param and value attributes.
jsp:getProperty Action
A <jsp:getProperty> action places the value of a Bean instance property into the
implicit out object. The String representation is sent to the HTTP response stream.
Unlike a scriptlet, which can get a value and assign it to a variable, the getProperty
action converts the Bean property value to a String and immediately adds that String
to the output stream. You cannot assign the value from this tag to a variable in most
containers.
You use jsp:getProperty to get the property values of beans that have been
referenced earlier in the JSP page. In Listing 8.5, you see several getProperty actions
for getting the JavaBean properties.
Regarding when this action takes place, in the following case, the jsp:getProperty
is executed regardless of whether a new bean was instantiated or an existing bean
already exists in memory.
<jsp:useBean id="beanName" ... />
<jsp:getProperty name="beanName"
property="propertyName" ... />
However, in the next case, the jsp:getProperty is executed only the first time the
JavaBean is instantiated. It is ignored if the JavaBean has already been loaded in
memory.
<jsp:useBean id="beanName" ... >
<jsp:getProperty name="beanName"
property="propertyName" ... />
</jsp:useBean>
Table 8.3 offers a quick overview of the getProperty attributes. There are only two,
less than the more complicated setProperty element.
Attribut Definition
e
property The name of the Bean property whose value you want to get. If you get a
propertyName that doesn't exist, you will generate an error.
JavaBeans have scope, just like all variables. You declare this in the jsp:useBean
element. If you declare the Bean in session scope, all JSP pages within that session
have access to the same JavaBean. Figure 8.3 illustrates object scope. The Page
scope is least visible. These objects are accessible only on the page where they were
created. Request scope means objects are accessible during the processing of the
request (that is, they can be transferred between pages as in a forward). The session
scope means objects are accessible throughout the life of the session. Finally, an
object with application scope can be accessed anywhere within the application. Given
the chart Page-->Request-->Session-->Application, objects on the left can see
objects on the right, but not the other way. So, objects with Page scope can see
objects with any other scope, but objects with Application scope can not see objects
with any other scope.
The following list describes the four scopes including Page, Request, Session, and
Application. There is an example snippet for each of the four types of scope that
Beans can have. I'd like to acknowledge and commend Alex Chaffee at jGuru for an
excellent set of examples in his FAQ (www.jguru.com/faq/view.jsp?EID=53309).
Page
The address bean is instantiated as a local variable. Since its scope is page, the
reference disappears once the JSP page is processed. It can't be referenced by
another JSP or servlet, even if a forward or include is used. The syntax is
<jsp:useBean id="address" class="que.scwcd.AddressBean" scope="page" />.
The following snippet demonstrates how to use it:
que.scwcd.AddressBean address =
new que.scwcd.AddressBean();
Request
The address bean is instantiated into the current request object. It can be accessed
by any JSP or servlet within the same request. This reference remains alive in any
other servlets/JSPs called by jsp:include and jsp:forward, or in ones called via a
RequestDispatcher object. The syntax is <jsp:useBean id="address"
class="que.scwcd.AddressBean" scope="request" />. The following snippet
demonstrates how to use it:
que.scwcd.AddressBean address =
(que.scwcd.AddressBean)request.getAttribute("address");
if (address == null)
{
address = new que.scwcd.AddressBean();
request.setAttribute("address", address);
}
Session
The address bean is instantiated into the current session. It can then be accessed by
any JSP or servlet responding to requests by the current user. The syntax is
<jsp:useBean id="address" class="que.scwcd.AddressBean" scope="session"
/>. The following snippet demonstrates how to use it:
HttpSession session = request.getSession(true);
que.scwcd.AddressBean address =
(que.scwcd.AddressBean)session.getAttribute("address");
if (address == null)
{
address = new que.scwcd.AddressBean();
session.setAttribute("address", address);
}
Application
The AddressBean bean is instantiated within the servlet context. It can be accessed
by any JSP or servlet within the servlet context, thus by any user. The syntax is
<jsp:useBean class="que.scwcd.AddressBean" scope="application" />. The
following snippet demonstrates how to use it:
que.scwcd.AddressBean address = (que.scwcd.AddressBean)
getServletContext()
.getAttribute("address");
if (address == null)
{
address = new que.scwcd.AddressBean();
getServletContext().setAttribute("address", address);
}
How do you use a declared Bean in JSP code? This objective wants you to be able to
access Beans with both XML elements and scriptlets. A declared JavaBean can be
accessed by the name specified in the id attribute of <jsp:useBean> by using
Scriptlets, Expressions, and XML elements. This chapter has already demonstrated all
three.
Table 8.5 gives you a list of three examples representing the three ways to access
Beans.
Access Example
EXAM TIP
What are the three ways to reference a bean in JSP? A JavaBean can be
referenced in three ways: through an expression, scriptlet, or XML tag.
Chapter Summary
The JavaBeans are components for use in JSP (at least as far as this exam is
concerned; they are used elsewhere, too). JavaBeans components are Java classes
that are easy to access from JSP. The JavaBeans are intended to be reused, so it is a
good idea to collect business logic in them, which takes the equivalent amount of
code out of JSP, a very good thing. There are no special classes to extend. A class
becomes a JavaBean if you follow certain design conventions, including a public
class, public constructor with no arguments, and get/set methods.
KEY TERMS
• JavaBean
• Bean properties
• XML
The JavaServer Pages specification supports JavaBeans with specific JSP language
elements. These elements include useBean, setProperty, and getProperty. With these
elements, you can easily initialize a JavaBean and get/set the values of its
properties. This chapter discussed all the exam objectives covering JavaBeans and
their use in JSP. For more information about using JavaBeans in JSP, please see
java.sun.com/products/javabeans.
Apply Your Knowledge
Review Questions
1:What is the purpose of JavaBeans?
A1: JavaBeans are intended to act as reusable components. You can encapsulate
business logic and properties in them. You can access the functionality and
properties from JSP. See "Introduction," in this chapter.
2:Why would you clutter JSP with JavaBeans code?
A2: Using JavaBeans doesn't clutter JSP; it has the opposite effect of cleaning up the
appearance of code within JSP. Since potentially many lines of scriptlet code are
transferred into a JavaBean, using Beans removes clutter from JSP code. Using
JavaBeans separates presentation and business logic (which also allows the
designers and the programmers to be separated, at least in theory). See
"Introduction," in this chapter.
3:What are the advantages of using JavaBeans?
A3: JavaBeans make JSP code easier to read and maintain. Also, the JavaBean itself
becomes a self-contained component so it also is easier to maintain. Lastly,
JavaBeans are easy to reuse and share among developers. See "Introduction," in
this chapter.
4:What makes a class a JavaBean?
A4: There are four things that make a class a JavaBean in JSP. They are a public class,
a public constructor with no arguments, public set and get methods to simulate
properties, and declaring a JavaBean within a JSP page. See "Creating JavaBeans,"
earlier in this chapter.
5:What was the original purpose for JavaBeans?
A5: The original purpose for JavaBeans was for visual component reuse. Inspired by
Visual Basic's amazing success, the designers of Java wrote a specification that
defined reusable components which were easy for IDEs to manipulate and present
to developers in a plug-and-play environment. See "Introduction," in this chapter.
Exam Questions
1:Which one of the following interfaces is implemented when declaring a JavaBean?
A. JavaBean
B. ServiceBean
C. HttpJavaBean
D. ServletBean
A. ServletRequest
B. HttpServletRequest
C. ServletResponse
D. HttpServletResponse
A. One
B. Five
A. response
B. request
C. session
D. application
E. page
A4: A. The response object cannot be used as the scope when using a JavaBean with
JSP. See "Scope of JavaBeans in JSP," earlier in this chapter.
5:Which of the following are used by servlet containers to set JavaBean properties?
A. cookies
B. form fields
C. memory
D. disk
A5: B. The JavaBean attributes are set when the container captures the form field
name-value pairs, and then calls the setter methods in the bean for the attributes
which have the same name as the form fields. See "Getting and Setting
Properties," earlier in this chapter.
6:Which of the following scopes best fits with this description: "An object inside this
scope is accessible from all pages processing the request during which the object
was created?"
A. page
B. session
C. application
D. request
A6: D. The request scope best fits the description given by the question. See "Scope of
JavaBeans in JSP," earlier in this chapter.
7:Is it impossible to share a page scope variable with another JSP or servlet?
A. Yes
B. No
C. Sometimes
D. Configurable
A7: A. This is true that it is impossible to share a page scoped variable with another
JSP or Servlet. See "Scope of JavaBeans in JSP," earlier in this chapter.
8:Given a form field named lastName, what is the get method for the
associatedJavaBean property?
A. public String getFirstName ()
B. {
C. return firstName;
D. }
E.
F. public String getFirstName (boolean returnValue)
G. {
H. if (returnValue)
I. return firstName;
J. }
K.
L. public String getFirstname ()
M. {
N. return Firstname;
O. }
P.
Q. public String get("FirstName")
R. {
S. return FirstName;
T. }
U.
A8: B. When you write a get method for a JavaBean property, use set or get followed
by the first letter of the property name capitalized. See "Getting and Setting
Properties," earlier in this chapter.
3. JavaBeans specification—
http://java.sun.com/products/javabeans/docs/spec.html.
8. Tomcat— an implementation of the Java Servlet 2.2 and JavaServer Pages 1.1
Specifications—http://jakarta.apache.org/tomcat/index.html.
This chapter covers the following Sun-specified objectives for Section 11, Designing
and Developing JSP Pages Using Custom Tags, and Section 12, Designing and
Developing a Custom Tag Library, of the exam:
• The taglib directives in a JSP page define the taglib prefix for your JSP
page. The prefix is the namespace of tags; it's how you refer to the given tag
library throughout the JSP page. The taglib directive creates a reference to
the prefix. The prefix tells the container which library you want. Once that is
done, you can use a custom tag, so called because it is your tag, not a
standard one that came shipped with the container. See "Taglib Directive."
11.3 Given a custom tag library, identify properly formatted custom tag use
in a JSP page. Uses include:
• A custom tag is simply a clean XML syntax that gives you easy access to the
tag handler methods. There are several ways to use these tags in a JSP page.
You can have an empty tag, use attributes, embed JSP code, and nest them.
This makes custom tags versatile. They are an elegant way to add
functionality to a JSP page without a lot of code.
12.1 Identify the Tag Library Descriptor element names that declare the
following:
• Tag Library Descriptor (TLD) is how you define your custom tags. It is in this
XML file that you tell the container which classes you will be using as tag
handlers and how you plan to use them.
12.2 Identify the Tag Library Descriptor element names that declare the
following:
• The name of a tag attribute
• The Tag Library Descriptor also takes attribute definitions for custom tags.
This is where you tell the container which attributes the tag handler expects
and whether it is required in the custom tags.
12.3 Given a custom tag, identify the necessary value for the BODYCONTENT
TLD element for any of the following tag types:
• Empty tag
• Custom tag that surrounds content that is used only by the tag
handler
• Custom tags, like all XML tags, can have a body. There are certain elements in
the Tag Library Descriptor that tell the container how you may use the custom
tag in a JSP page. A custom tag may be empty, have JSP in it, or have
content that is special to the tag handler.
• The JSP specification allows container builders to employ an event model for
processing custom tags. When a container encounters a custom tag, it
triggers an event (doStartTag()). These events occur during processing of a
request of a JSP page. You write a class that becomes the tag handler, a class
that extends the TagSupport abstract class (doStartTag(), doEndTag()…).
This section addresses what these event methods are and when they are
invoked.
• DOSTARTTAG()
• DOAFTERBODY()
• DOENDTAG()
• PAGECONTEXT.GETOUT()
• Each of the event methods has return values. These return values affect how
the container proceeds. For example, the SKIP_BODY value tells the container
to ignore the body of the tag, if any exists. You can tell the container to stop
processing the actual JSP page, too, and more.
• DOAFTERBODY()
• DOENDTAG()
• These constants tell the container what to do with either the body of the
custom tag or the entire JSP page. For example, you may want to repeat the
tag processing in an iteration situation. You can also stop the repetition with
another constant.
12.7 Identify the method in the custom tag handler that accesses:
• Remember the implicit variables in JSP? They are available to your custom tag
handler. This section covers the syntax and the methods that you use to
manipulate implicit variables such as the Request, Response, and Session
objects.
12.8 Identify methods that return an outer tag handler from within an inner
tag handler.
• The JSP specification allows you to nest tags. That is a very powerful
architecture. However, because of the ability to nest there will be times when
you need to access one of the outer tags from the inner one. This section
covers this capability.
OUTLINE
Introduction
Taglib Directive
Custom Tag
Chapter Summary
Exam Questions
STUDY STRATEGIES
• Tag libraries are very powerful. There is a lot to them. Be sure to build a tag
library as described in this chapter because the exam will expect you to
understand how they work and how the various pieces relate to one another.
• Make sure you know the basic syntax of the tag library directive and the Tag
Library Descriptor.
• Take some time to play with a few free tag libraries. Doing so will provide you
with a shortcut to understanding how JSP implements tag libraries, without
requiring you to write tag libraries from scratch.
Introduction
You'll recall how JavaBeans provided a way to encapsulate functionality in classes
accessible via tags in JSP pages using XML notation. Although the reference to such a
JavaBean allows you to access attributes and methods via scriptlets, the XML
notation itself is limited to getting and setting properties in the JavaBean. Once you
have the reference, as mentioned, you can treat the JavaBean like any object in
scriptlets by calling its methods and getting/setting its properties. However, in many
cases, you may prefer to use an XML-based syntax for invoking these methods rather
than having to invoke them via a scriptlet. Sun's answer is called a tag library.
A tag library is similar to JavaBeans in that you can reference a class from JSP using
XML notation. However, unlike JavaBeans, tag libraries have a specific lifecycle
protocol. So, whenever you use a tag library tag, the container calls the lifecycle
event methods in your tag handler (doStart, doStartTag, doAfterBody). Typically,
you use these methods to return a string, which the container places inline where
the tag is located in the JSP page.
A tag library maps XML tags to underlying class methods in a Tag Library Descriptor
(.tld) file. This file defines the custom tags that you can use in JSP to access the
associated Java class. Your container (that is, Tomcat) uses the TLD to convert the
XML in your JSP page into Java code. TLD files are written in XML notation. For
example, Listing 9.1 is an example of how you can define a tag.
Listing 9.1 The Source Code for Defining a Tag in a Tag Library
Descriptor
<tag>
<name>whatColorIsIt</name>
<tagclass>examples.ColorTagHandler</tagclass>
<info>Simply echos back some text</info>
<attribute>
<name>color</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
The following section explains how the container uses a Tag Library Descriptor file to
expand the functionality of a JSP page utilizing custom tags.
WARNING
Be careful about refreshing files! There is a little weirdness in some containers
when it comes to refreshing files. If you update the tag handler (by changing code
and then recompiling), Tomcat will see the new class and its changes after a few
seconds. If you change the web.xml file, Tomcat will ignore the changes. You have to
recycle Tomcat because this file is part of its initialization. Also, if you change your
Tag Library Descriptor (*.tld), your changes will not take effect at first. Notice that
the container converts your custom tags into Java calls during the JSP page
translation, so any change to the tag library itself won't take effect until the next
translation of the JSP pages that refer to that library. When the container translates
and recompiles a JSP page, the changes to the tag library will finally take effect. So,
the custom tag is converted to Java during the translation step. Therefore, if you
want to change the tag library, you must force Tomcat to recompile the JSP page that
refers to it.
Before discussing the details, let's review a simple example. This example will
provide you with a nice overview of how tag libraries work. Our example here
involves four files. The tag handler is an object invoked by a Web container. It
processes the calls based on the custom tag in the JSP page. This is where the bulk
of the work happens. It is a class that extends the TagSupport abstract class
(doStartTag(), doEndTag()...). The tag handler can retrieve all the other implicit
objects (request, session, and application) accessible from a JSP page through the
page context object (javax.servlet.jsp.PageContext). The next file is the Tag
Library Descriptor (TLD). A TLD is an XML document that describes a library as a
whole and each tag contained in the library. TLDs are used by a Web container to
validate the tags. JSP page development tools also peek at this. The web.xml file
tells the container where the tag library is located. When the JSP page references the
tag library with a URI, the container maps that URI (which could be anything and
doesn't have to be real) to a file path. Lastly, the JSP page itself uses special XML
tags to reference the supporting class called a tag handler so you can access
attributes and methods using a clean XML convention.
Table 9.1 describes the four files involved in this simple example.
File Description
YourTagHandler.java The tag handler class that does the work, similar
to a JavaBean.
YourTagLibraryDefinition.tld The actual tag library that defines the tag names
and associates them with classes.
The web.xml file is used as the deployment descriptor (see Chapter 10, "Deploying
Web Applications and Components"). The deployment descriptor defines the
elements and configuration information of a Web application. In it, you define
elements to support the Web application within a servlet container, including
ServletContext init parameters, session configuration, and servlet declarations.
The specification defines an optional taglib element that has become standard for
the latest containers. The taglib element is used to describe a JSP tag library. The
syntax for the taglib element in the web.xml file is <!ELEMENT taglib (taglib-
uri, taglib-location)>. The required taglib-location element contains the
location (as a resource relative to the root of the Web application) of the Tag Library
Descriptor file for the tag library. The taglib-uri element describes a URI, relative
to the location of the web.xml document, that identifies a tag library used in the Web
application. You use the URI to give a tag library a unique address or namespace.
The taglib element is simply a mapping of a URI to a tag library file. The taglib-
location element is a file path relative to the Web application directory root. It goes
in the web.xml file so that upon startup, the container is aware of the URI and the
library it points to. When you use an XML tag that has this URI in it, the container
will know that you are really pointing to a specific file. In the web.xml file
(TOMCAT_HOME\webapps\examples\WEB-INF), you tell the container where to find
your tag library, as shown in Listing 9.2.
<body>
<yourLibrary:whatColorIsIt color="red"/>.
<br />
Your first tag library is functioning.
You are closer to passing the exam.
</body>
</html>
The taglib directive creates a reference to the prefix, yourLibrary in this case. The
prefix tells the container which library you want. Once that is done, you can use a
custom tag, so called because it is your tag, not a standard one that came shipped
with the container. Within that library can be many tags. You must specify which tag
handler to use, in this case whatColorIsIt. This class has an attribute called color.
We are setting it to red in the previous custom tag. The main point here is not the
functionality itself; you must use the tag name to which the tag handler class is
mapped. Using custom tags cleans up the JSP code considerably. In the extreme
case, we can write the entire JSP page in XML, making it easier to use tools that
could check the validity of the page and build the page. Even if you only replace a
few scriptlet-JavaBeans portions with custom tags, you are ahead.
When this JSP page is called, the container will then find the library and insert the
appropriate Java into the servlet as part of the translation step.
<tag>
<name>whatColorIsIt</name>
<tagclass>examples.ColorTagHandler</tagclass>
<info>Simply echos back some text</info>
<attribute>
<name>color</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
The "tag library" is not merged into the servlet-file for the JSP page; rather, custom
tags in the JSP file are translated into Java code that executes the lifecycle method
for the tags used in the JSP page. Although each vendor will do this somewhat
differently, let's look at how Tomcat does it, because its approach is typical. The
following is a slightly edited snippet from yourTagLibrary$jsp, which Tomcat
generated in the TOMCAT_HOME\work\localhost\examples\jsp folder:
jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=ISO-8859-1");
pageContext = _jspxFactory.getPageContext(this, request,
response, "", true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
out.write("<html>\r\n<head>\r\n");
out.write("\r\n</head>\r\n\r\n<body>\r\n");
if (_jspx_eval_yourLibrary_whatColorIsIt_0 ==
javax.servlet.jsp.tagext
.BodyTag.EVAL_BODY_BUFFERED)
throw new JspTagException("Since tag handler class"+
" examples.ColorTagHandler does not implement "+
"BodyTag, it can't return BodyTag.EVAL_BODY_TAG");
if (_jspx_eval_yourLibrary_whatColorIsIt_0 !=
javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
do {
} while (_jspx_th_yourLibrary_whatColorIsIt_0
.doAfterBody() == javax.servlet.jsp.tagext
.BodyTag.EVAL_BODY_AGAIN);
}
if (_jspx_th_yourLibrary_whatColorIsIt_0.doEndTag()
== javax.servlet.jsp.tagext.Tag.SKIP_PAGE)
return;
} finally {
_jspx_th_yourLibrary_whatColorIsIt_0.release();
}
out.write(".\r\n<br />\r\nYour first tag library "+
"is functioning. You are closer to passing the "+
"exam.\r\n</body>\r\n</html>\r\n\r\n\r\n");
As you can see, the container sets the color attribute specified in the JSP page
custom tag with _jspx_th_yourLibrary_whatColorIsIt_0.setColor("red"). Then
it invokes the doStartTag() method automatically. The setColor() and
doStartTag() methods are in the tag handler.
The tag handler is a class that implements an interface, which makes it a tag
handler. Usually a tag handler class extends TagSupport (which implements
IteratorTag interface). The tag handler overrides the tag processing event methods
of the TagSupport class to process the tag. Like you saw in JavaBeans (see Chapter
8, "Extend JSP with JavaBeans"), the container converts attribute tags in XML to
get/set calls. The tag handler (TOMCAT_HOME\webapps\examples\ WEB-
INF\classes\examples\ColorTagHandler.java) used in this example looks like
Listing 9.4.
import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Given a color, simply send back the value.
*
* @author QUE reader
*/
public class ColorTagHandler
extends javax.servlet.jsp.tagext.TagSupport
{ // makes this a tag handler^^^^^^^^^^
/**
* Processes this tag.
*/
public int doStartTag() throws JspException
{// ^^^^^^^^^^ is called automatically as
// part of tag library feature
return EVAL_BODY_INCLUDE;
}
/**
* JavaBeans-style property setter for color.
*
* @param s a String representing the color
*/
public void setColor(String s)
// ^^^^^^^^ is called like a JavaBean
// setter method
{
this.color = s;
}
}
All together, this trivial example produces the following HTML when you browse to
http://localhost:8080/examples/jsp/yourTagLibrary.jsp:
<html>
<head>
</head>
<body>
The current color is: red.
<br />
Your first tag library is functioning.
You are closer to passing the exam.
</body>
</html>
As the warning mentions, be careful about refreshing files. The following list will help
you know when changes to the given file will take effect. From slowest to take effect
to quickest, they are: web.xml, YourTagLibraryDefinition.tld, YourTagHanlder.java,
and yourJSP.jsp. Remember, the container converts your custom tags into Java calls
during the JSP page translation. That is why changes to the tag library itself won't
take effect until the next translation of the JSP pages that refer to that library.
With JSP 1.2, you no longer have to pack your pages with scriptlets. Web authors
also don't have to know Java to create sophisticated Web applications. Making
functionality available to Web authors is no problem, as Step by Step 9.1 proves.
STEP BY STEP
9.1 Creating a New Tag Library
1. Write and compile a simple tag handler similar to the
ColorTagHandler example that services the custom tag in your JSP
(JSP custom tag attribute invokes a setter method in tag handler).
Place the tag handler Java class files for your tags in the WEB-
INF/classes directory of your Web application.
2. Write the tag library descriptor (TLD), which defines the tag library
including the name of the tag handler class and attributes. Place it in
its directory, which you declare in the deployment descriptor
(CATALINA_HOME/webapps/examples/WEB-INF/veltag.tld). An
example is given earlier in this chapter.
The previous steps showed you how to create a new tag library and use it in a Web
page. As you may remember, JavaBeans came close to serving the same purpose,
but didn't go far enough. For functionality beyond getting and setting properties, you
had to use scriptlets. Now, tag libraries allow you to use any custom tag in place of
scriptlets as noted in the previous steps.
The following goals represent the hope Sun has for tag libraries:
• Simple. People who have less geek in them should be able to understand and
use them.
• Flexible. Although the JSP specification currently only allows Java scripts, the
architecture is designed to add other scripting languages.
• Reusable. Once you write a tag handler, like a JavaBean, you can use it
easily in many projects.
All these goals reflect the same hope for Java in general. I feel tag libraries are the
gem of the current JSP specification, above even JavaBeans. The more tag libraries
you include in your project, the better the design.
As you can see, creating a tag library is not as daunting as you might have expected.
Now that you have a solid overview of this portion of Web component development,
let's look at the details that the exam will expect you to know.
Taglib Directive
11. 2 Identify properly formatted TAGLIB directives in a JSP page.
In Chapter 7 where we covered JSP, you'll remember how I said directives are a
communication link between the JSP page and the JSP container. That is, they don't
contribute anything into the current output stream. There are three directives:
include, page, and taglib. The taglib directive has the following syntax:
<%@ taglib uri="tagLibraryURI" prefix="tagPrefix" %>
Tag libraries make it easy to embed functionality into JSP documents. Instead of
writing messy scriptlets, you can use custom XML tags that make your intentions
more explicit. You are better able to separate presentation from business logic with
custom tags.
You add the methods defined in the Tag interface such as setPageContext(),
doStartTag(), and doEndTag(). Once you have written your tag handler, you can
take advantage of the new functionality in your JSP page. Start by including the
taglib directive at the top of the page like so:
<%@ taglib uri="/WEB-INF/jsp/myTaglib.tld"
prefix="myTag" %>
...
<body>
The custom tag returns: <myTag:myMethod/>
...
The taglib directive only has two attributes. They are the uri and the prefix.
Remember that the uri names the tag library with the same namespace as you used
in the web.xml deployment descriptor. The prefix is any legal identifier. Notice how
you can use many taglib directives in a single page, but the prefix defined in each
must be unique.
Custom Tag
11.3 Given a custom tag library, identify properly formatted custom tag use
in a JSP page. Uses include:
The custom tag is a convention that allows you to have the container call the tag
library life cycle event methods (for example, doStartTag), including the attribute
get/set calls automatically invoked when attributes are declared in the custom tag.
doStartTag and doEndTag methods are called when the JSP page request is
processed. The following is an example of an empty custom tag (no body):
<tagHandlerPrefix:customTagName />
Table 9.2 lists the four ways to use a custom tag.
Tag Description
<libraryPrefix:handlerName
parameterName="value"> A custom tag with a body. The body
<%= 23 * counter %> can contain core tags, scripting
<b>Congratulations!</b> elements, HTML text, and tag-
</libraryPrefix:handlerName> dependent body content between
the start and end tags.
<library:outerTag>
<library:innerTag> This syntax is how you nest custom
</library:innerTag></library:outerTag> tags. The XML is easy, but the
handler is more involved. Note that
the following is wrong:
<X><Y></X></Y>.
This section of the exam covers the Tag Library Descriptor. The Descriptor is the file
that defines a custom tag in JSP. In the Descriptor, you use a separate element to
define each new tag in the tag library. More simply stated, it's how you define a tag.
Table 9.3 lists the elements named in the previous objectives.
Element Description
While Table 9.3 lists the basic elements you should use to define a custom tag, Table
9.4 continues with the definition of the attribute portion of a custom tag.
Table 9.4. Attribute Element of a Custom Tag
Element Description
• Empty tag
• Custom tag that surrounds content that is used only by the tag
handler
This objective tells us that Sun includes questions on the exam regarding custom
tags. You then have to determine what the Tag Library Descriptor looks like.
As shown in Table 9.3, there are three ways to use the body of a custom tag. Table
9.5 matches exam examples with the appropriate Descriptor bodycontent element.
<tagLibrary:myTag <bodycontent>empty</bodycontent>
firstName="Patricia"
lastName="Trottier" ... />
The empty (tag has no body) and JSP options (default and interpreted if present) are
straightforward. The tagdependent option is the strange one. This means the text is
sent to the tag handler, but the text is not sent to the output stream, unless the tag
prints it to the stream.
• DOSTARTTAG()
• DOAFTERBODY()
• DOENDTAG()
• PAGECONTEXT.GETOUT()
• DOSTARTTAG()
• DOAFTERBODY()
• DOENDTAG()
These objectives are closely related. That is why I cover them together here.
Basically, this part of the exam covers the event methods that the container triggers
when processing your custom tags along with these method return constants. There
are only four methods that you have to study and a few constants.
Table 9.6 lists the return values possible for the custom tag event methods. They are
described in more detail immediately after the discussion about these fields. These
return constants tell the container what to do after processing the triggered method.
SKIP_BODY Skip body evaluation. Stop processing the JSP after the current
custom tag (doStartTag(), doAfterBody()).
SKIP_PAGE Stop processing the JSP after the current custom tag
(doEndTag()).
Table 9.7 lists the methods that are triggered when the container processes custom
tags.
PageConext.getOut() This is how you add the output stream directly. This method
returns javax.servlet.jsp.JspWriter.
Listing 9.5 illustrates a very simple example, as an abstract class, of an example tag
handler that shipped with Tomcat.
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
The key to answering questions about a JSP page's implicit variables and attributes is
to use the PageContext object. An instance of this object provides access to all the
namespaces and most attributes for a JSP page. You can grab the implicit objects
with the following methods:
• getOut(). This method returns the current JspWriter stream being used for
the client response.
• getRequest(). This method returns the ServletRequest for this JSP page
request.
• getResponse(). This method returns the ServletResponse for this JSP page
request.
• getSession(). This method returns the HttpSession for this JSP page request
or null.
• getServletConfig(). This method returns the ServletConfig for this JSP page
request.
There is nothing special about using these methods in a tag handler. The point is that
you are very likely to use one or more of them when writing a tag handler.
Similar to the previous list of methods, the following methods are used to access the
attributes in your tag handler for a given JSP page:
• setAttribute(). This method registers the name and object specified with
appropriate scope semantics.
• getAttribute(). This method returns the object associated with the name in
the page scope or null if not found.
• findAttribute(). This method searches for the named attribute in the page,
request, session (if valid), and application scope(s) respectively and returns
the associated value or null.
The following methods provide support for forwarding, inclusion, and error:
The following methods are most helpful when trying to reach another tag from an
inner tag:
• getParent(). This method finds the parent (closest enclosing tag handler) for
this tag handler. You might do this to navigate the nested tag handler
structure at runtime.
Chapter Summary
Tag libraries and JavaBeans are closely related. JavaBeans provide a way to
encapsulate functionality in classes accessible via tags in JSP pages, as well as by
using XML notation. Tag libraries also provide this capability. JavaBeans provide easy
access only to get/set methods, but tag libraries have more robust functionality to
allow you to respond to events that are triggered by the start, body, and end of a
custom tag.
KEY TERMS
• Custom tags
• Tag libraries
• Nested tags
• Taglib directive
• doStartTag()
• doEndTag()
Tag libraries are really an extension of JavaBeans in JSP. Although they get and set
like JavaBeans, they do much more if you want them to. You can access this extra
functionality with XML tags in JSP. You define these XML tags. That is why they are
called custom tags.
There are many commercial and free tag libraries available on the market. I
recommend you peruse a few to see how they are being used. Although tag libraries
are a deep enough topic to deserve a whole book alone, the exam is restricted to the
main aspects of this technology, which this chapter is careful to observe.
A2: A tag library maps XML tags to underlying class methods in a Tag Library
Descriptor (TLD) file. This file defines the XML tags that you can use in JSP to
access the associated Java class. Your container (i.e., Tomcat) uses the TLD to
convert the XML in your JSP page into Java code as you've seen. The tags you add
to JSP page, the TLD files themselves, and the Web Deployment Descriptor are all
written in XML notation. See "Introduction."
3:What is the main point of using tag libraries?
A3: In Chapter 8, you learned about JavaBeans and how to use them in JSP pages.
The idea behind this is to allow the developer to replace Java code in the JSP page
with XML notation. This is cleaner and reduces errors. JavaBeans is a good start,
but doesn't go far enough. We want to access more functionality with XML tags,
beyond getting and setting attributes. Tag libraries allow you to design custom
tags, which are tags of your design backed up with tag libraries. This gives us a
powerful implementation of a wide range of functionality, using clean XML notation
within JSP. See "Creating a Tag Library Example."
4:What should a developer be concerned about when refreshing files associated with
tag libraries?
A4: If you update the tag handler (change code and then recompile), the container will
see the new class and its changes after a few seconds. However, if you change the
web.xml file, Tomcat will ignore the changes. You have to stop and restart Tomcat
because this file is part of its initialization. Also, if you change your Tag Library
Descriptor (*.tld), your changes will not take effect at first. Notice that the
container converts your custom tags into java calls during the JSP page
translation, so any change to the tag library itself won't take effect until the next
translation of the JSP pages that refer to that library. See "Creating a Tag Library
Example."
Exam Questions
1:Which three of the following is part of the Tag Library Descriptor element?
A. namespace
B. name
A. url
B. uri
C. prefix
D. name
A2: A and D. The taglib directive only takes two attributes, uri and prefix. See
"Taglib Directive."
3:Which file does the following DTD element definition apply to: <!ELEMENT taglib
(taglib-uri, taglib-location)>?
A. web.init
B. YourTagHandler.java
C. YourTagLibraryDefinition.tld
D. web.xml
A3: D. The taglib element is used to describe a JSP tag library. The syntax for the
taglib element in the web.xml file is <!ELEMENT taglib (taglib-uri,
taglib-location)>. The required taglib-location element contains the
location and the taglib-uri element describes a URI identifying a Tag Library
used in the Web application. You use the URI to give a tag library a unique
address or namespace. See "Taglib Directive."
4:Which of the following is the Web Deployment Descriptor, the purpose of which is
to configure a Web application?
A. web.xml
B. web.init
C. YourTagLibraryDefinition.tld
D. YourTagHandler.java
A4: A. The web.xml file is used as the deployment descriptor (see Chapter 10,
"Deploying Web Applications and Descriptors"). The deployment descriptor
defines the elements and configuration information of a Web application. In it
you define elements to support the Web application within a servlet container,
including ServletContext init parameters, session configuration, and servlet
declarations. See "Taglib Directive."
5:Which three of the following files is part of a simple tag library?
A. web.xml
B. web.init
C. YourTagLibraryDefinition.tld
D. YourTagHandler.java
A5: A, C, and D. All of these files could be used as part of your tag library except
option B because web.init is not a file defined by the specification. Also, you need
a JSP file such as yourJSP.jsp. See "Creating a Tag Library Example."
6:How do you declare a tag library within a JSP page?
C. <libraryPrefix:handlerName />
A. web.xml
B. Xerces
C. Xmlspy
A. TagSupport
B. TagProcess
C. Tag
D. TagStart
A9: A. Your tag handler is a class that extends the TagSupport abstract class if it has
doStartTag() and doEndTag() methods. See "Creating a Tag Library Example."
10:What does the container do during translation when it encounters a custom tag
in a JSP page?
A. It converts the XML notation into Java calls, inserted into the Java that
resulted from the page translation.
C. It converts it to scriptlets.
4. A good overview of tag libraries from BEA. This is helpful because they use
their own excellent product, WebLogic, which will differ somewhat from
Tomcat (which is used in this book):
http://edocs.bea.com/wls/docs61/taglib/overview.html#362351.
6. More Servlets and JavaServer Pages by Marty Hall. This is also very good:
http://www.moreservlets.com/.
7. Designing JSP Custom Tag Libraries by Sue Spielman is a very short, but
excellent snapshot of tag libraries:
http://www.onjava.com/pub/a/onjava/2000/12/15/jsp_custom_tags.html.
8. Sun's reference page has many good links for tag libraries:
http://java.sun.com/products/jsp/taglibraries.html.
Chapter 10. Deploying Web
Applications and Components
OBJECTIVES
A Web application is made up of all the servlets, HTML pages, classes, and other
resources that act as a single application on a Web server. That it is called a Web
application is not surprising, but one facet that is interesting is that a Web application
can be bundled and run on multiple containers from multiple vendors. In other words
you can zip the whole thing up into one Web Archive (WAR) file and give it to the
others to install.
The main focus of this chapter is defining what a Web application is, the many parts
of one, and how it physically resides on a file system. We will cover these ideas by
addressing the following Sun-specified objectives for the Web application section of
the Sun Certified Web Component Developer exam:
2.1 Identify the structure of a Web Application and Web Archive file, the
name of the WebApp deployment descriptor, and the name of the directories
where you place the following:
2.2 Match the name with a description of purpose or functionality, for each
of the following deployment descriptor elements:
• Servlet instance
• Servlet name
• Servlet class
• Initialization parameters
• There are many elements in the web.xml descriptor file. This section, and a
few more like it, wants you to be familiar with the purpose of these elements
and how to use them. This grouping concerns servlets. Although you can add
servlets to your Web application without listing them in the deployment
descriptor, it makes sense to add the most important ones.
3.2 Identify the WebApp deployment descriptor element name that declares
the following features:
• The purpose of this objective is to teach you how to configure the deployment
descriptor to handle exceptions. Because your Web application may have
errors, this section concerns the servlet specification where it addresses how
the deployment descriptor configures the Web container to handle exceptions.
• Authentication, authorization
• Data integrity
• Auditing
• Malicious code
6.2 Identify the deployment descriptor element names, and their structure,
that declare the following:
• A security constraint
• A Web resource
• A security role
• The purpose of this objective is to teach you about the security elements in
the deployment descriptor. These elements are what you use to add security
constraints with one or more Web resource collections such as a security role
and user roles that should be permitted access to this resource collection.
• Authentication has been a big part of security from the beginning. Web
applications are designed with four types of authentication out of the box. You
can always add more types, but these are a good start.
• Chapter 9, "Customize JSP with Tag Libraries," covers the subject of tag
libraries in detail. It tells you that they are similar to JavaBeans in that you
can reference a class from JSP using XML notation. The objective covered in
this chapter is intended to ensure that you understand how to specify tag
libraries (URI and location) within a given Web application.
OUTLINE
Introduction
context-param
Element
Example
listener
Element
Example
servlet
Element
Example
servlet-mapping
Element
Example
session-config
Element
Example
welcome-file
Element
Example
error-page
Element
Example
taglib
Element
Example
security-constraint
Element
Example
login-config
Element
Example
security-role
Element
Example
Authentication Types
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• The Web application descriptor is just an XML document. Rather than trying to
memorize the DTD, write a few descriptors and recycle the servlet container
to see the effect it has. Also, notice that most of the elements make sense in
context, so study the examples in this chapter.
• Make sure you know the basic Web application directory structure of an
application.
• There isn't much syntax to study for this part of the exam. You can still
practice with the examples by making changes and recycling the server (for
example, Tomcat).
Introduction
Unlike simple standalone applications, a Web application has built-in complexity. The
code you write won't take effect unless it is compiled and placed into the proper
directory. Also, you should be mindful of how the server is configured. What if the
session timeout is only 20 minutes? Is that appropriate for your application? What do
you give a customer when you deploy your Web application? It is difficult to write an
installation script for a Web application. The target installation machine may have a
non-standard configuration. For example, it may be a Web farm.
The Web application is an extension of the Web server. Therefore, you have to plug
your files into the server's directory structure. The servlet standard does tell how to
make your directories for a default installation. The exam will assume this default
configuration.
The good news is that most of what you need to know involves XML. There is little
syntax to memorize. This part of the exam is about being familiar with the web.xml
DTD and where to put your files. The DTD itself isn't difficult if you study the
purposes of the main elements. Actually, it is a nice architecture to have this
web.xml document instead of using initialization text files with non-standard
definitions that have been the normal practice for so long.
The application needs a reference point within the hierarchical structure. Here, let's
call it TOMCAT_HOME. This represents the root of your server (Tomcat) installation,
not your Web application root. In this book, I used Tomcat on a Windows machine
(Dell Inspiron). Except for using a forward slash instead of a backward one, and the
drive letter, it is the same for Unix installations.
Within a generic context, there are three directories in focus here. The installation
directory will vary wildly between installations. This directory is not on the exam.
There is a structure for how the container is supposed to be used once you get deep
enough into the Web application deployment. Whatever the installation directory,
there are predefined subdirectories, one each for the WebApp deployment descriptor,
the class files, and the auxiliary JAR files. The Web application structure you'll be
questioned about is shown in Table 10.1.
The following is the Web application structure for a small sample Web application:
/index.html
/welcome.jsp
/store.jsp
/images/logo.gif
/images/background.gif
/WEB-INF/web.xml
/WEB-INF/taglib.tld
/WEB-INF/lib/shoppingBean.jar
/WEB-INF/classes/com/myCompany/servlets/Shopping.class
/WEB-INF/classes/com/ myCompany/util/CurrencyFormat.class
Although the actual paths are not on the exam, seeing where the files actually go
illustrates what is going on. For example, I installed Tomcat at
C:\dev\java\jakarta-tomcat-4.0.1 on my machine. I would then refer to this
directory as TOMCAT_HOME, or something similar. Tomcat knows to look into the
C:\dev\java\jakarta-tomcat-4.0.1\webapps directory for Web applications. From
here you will configure Tomcat, or another container, with XML files. For example,
Tomcat installs with an example application. In the C:\dev\java\jakarta-tomcat-
4.0.1\conf or just TOMCAT_HOME\conf directory there is a server.xml file. Tomcat
uses this to configure itself upon starting. There is a context element that you use to
map your application's URL to the actual directory path. The following is how you get
an examples application:
<!-- Tomcat Examples Context -->
<Context path="/examples" docBase="examples" debug="0"
reloadable="true">
So, now that you have an examples Web application, the actual root directory is this:
TOMCAT_HOME\webapps\examples. If you had the file
TOMCAT_HOME\webapps\examples\hello.jsp you would call this file with
http://localhost:8080/examples/hello.jsp (just change the port to whatever
one you have your server listening to). Notice how Tomcat converts the URL into a
path. Table 10.2 shows you how Tomcat converts several URLs into paths.
installation C:\dev\java\jakart
root TOMCAT_HOME.
NOTE
Mapping URLs to Paths! There are many ways to map a URL to an actual path. The
server.xml maps a Web application name to a directory under the
TOMCAT_HOME\webapps directory. The web.xml maps servlet names to paths, too. On
top of all this, the server can have other virtual maps and configurations.
Let's create a WAR file. After you have created your application directory, and sub-
directories including the WEB-INF directory, you can create a WAR file. You use the
"jar" utility from the Java Development Kit to create the WAR file. Follow these steps:
That is how you create it. Where does the myApplication.war file go? To test your
new WAR file, copy it to the webapps directory and then rename the myApplication
directory to, say, myApplicationTemp. Now, recycle the server and point your
browser to one of your old servlets or JSP pages.
• Servlet instance
• Servlet name
• Servlet class
• Initialization parameters
3.2 Identify the WebApp deployment descriptor element name that declares
the following features:
6.2 Identify the deployment descriptor element names, and their structure,
that declare the following:
• A security constraint
• A Web resource
• A security role
This section of the exam is primarily a test of your familiarity with the XML DTD for
the Servlet 2.3 deployment descriptor. Remember that the deployment descriptor of
a Web application is the web.xml file. This file is located in the WEB-INF directory
whether in the file system or in a WAR file. You don't have to memorize the whole
XML DTD (see http://www.w3.org/TR/REC-xml#dt-element for an element
definition). There are 77 elements total, but you don't have to know all of them and
many are trivial like name and description. This isn't painful if you use a little
shortcut for the task. Some folks use a mnemonic from the first letter of the tags
listed in the exam objectives. The following is the root element for the descriptor:
<!ELEMENT web-app (icon?, display-name?, description?,
distributable?, context-param*, filter*, filter-mapping*,
listener*, servlet*, servlet-mapping*, session-config?,
mime-mapping*, welcome-file-list?, error-page*, taglib*,
resource-env-ref*, resource-ref*, security-constraint*,
login-config?, security-role*, env-entry*, ejb-ref*,
ejb-local-ref*)>
The main elements are defined in Table 10.3.
Element DTD
Element DTD
As previously stated, you don't have to know the entire DTD. Out of the root element
you should focus on these:
C = <context-param>
L = <listener>
S = <servlet>
S = <servlet-mapping>
S = <session-config>
W = <welcome-file-list>
E = <error-page>
T = <taglib>
S = <security-constraint>
L = <login-config>
S = <security-role>
One shortcut comes from Ricardo Cortes and Kevin Postlewaite whose posts on
JavaRanch were very helpful (http://saloon.javaranch.com/cgi-
bin/ubb/ultimatebb.cgi?ubb=get_topic&f=18&t=001389). Mr. Postlewaite's
unforgettable phrase is CLaSSSic WET SeaLS. Perhaps you can also remember mine,
which is CLaSS SWEaTS LotS.
context-param
The context-param element declares the Web application's servlet context-
initialization parameters.
Element
<!ELEMENT context-param (param-name, param-value,
description?)>
Example
<web-app>
...
<context-param>
<param-name>TOMCAT_ROOT</param-name>
<param-value>C:\dev\java\jakarta-tomcat-4.0.1
</param-value>
</context-param>
<context-param>
<param-name>Support</param-name>
<param-value>[email protected]</param-value>
</context-param>
...
</web-app>
listener
The listener element defines the deployment properties for a Web application
listener bean.
Element
<!ELEMENT listener (listener-class)>
<!ELEMENT listener-class (#PCDATA)>
Example
<web-app>
...
<listener>
<listener-class>listeners.MyListener</listener-class>
</listener> ...
</web-app>
servlet
The servlet element is how you define a servlet in a Web application. The servlet
element establishes a mapping between a servlet name and the fully qualified name
of the servlet class. Of course, you don't have to name all your servlets in the
web.xml file. However, there are servlets that you may need defined here so the
container can load them upon starting (load-on-startup element), for example.
Element
<!ELEMENT servlet (icon?, servlet-name, display-name?,
description?, (servlet-class|jsp-file), init-param*,
load-on-startup?, run-as?, security-role-ref*)>
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT servlet-class (#PCDATA)>
<!ELEMENT load-on-startup (#PCDATA)>
<!ELEMENT run-as (description?, role-name)>
<!ELEMENT security-role-ref (description?, role-name,
role-link?)>
Example
<web-app>
...
<servlet>
<servlet-name>
MyTestServlet
</servlet-name>
<servlet-class>
MyTestServlet
</servlet-class>
</servlet>
...
</web-app>
servlet-mapping
The servlet-mapping element defines a mapping between a servlet and a URL
pattern. When a request is received by the container it must determine which servlet
should handle it. Using the deployment descriptor, you can map certain paths
(aliases) to a specific servlet. You define this mapping with the servlet-mapping
element. The alias is appended after the context root in an HTTP request URL.
Element
<!ELEMENT servlet-mapping (servlet-name, url-pattern)>
Example
<web-app>
...
<servlet-mapping>
<servlet-name>
MyTestServlet
</servlet-name>
<url-pattern>
/testServlet
</url-pattern>
</servlet-mapping>
...
</web-app>
session-config
The session-config element defines the session parameters for this Web
application such as the session timeout, which defines the default session timeout
interval for all sessions created in this Web application.
Element
<!ELEMENT session-config (session-timeout?)>
<!ELEMENT session-timeout (#PCDATA)>
Example
<web-app>
...
<session-config>
<session-timeout>30</session-timeout>
</session-config>
...
</web-app>
welcome-file
The welcome-file element contains a filename to use as a default file, such as
index.html.
Element
<!ELEMENT welcome-file (#PCDATA)>
Example
<web-app>
...
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
...
</web-app>
error-page
The error-page element contains a mapping between an error code or exception type
to the path of a resource in the Web application.
Element
<!ELEMENT error-page ((error-code | exception-type),
location)>
<!ELEMENT error-code (#PCDATA)>
<!ELEMENT exception-type (#PCDATA)>
Example
<web-app>
...
<error-page>
<error-code>404</error-code>
<location>/NotFoundErrorPage</location>
</error-page>
...
</web-app>
taglib
The taglib element is used to describe a JSP tag library, including the tag library
location (Tag Library Description file) and the URI for it which is a unique namespace
identifying a tag library used in the Web application.
Element
<!ELEMENT taglib (taglib-uri, taglib-location)>
<!ELEMENT taglib-location (#PCDATA)>
<!ELEMENT taglib-uri (#PCDATA)>
Example
<web-app>
...
<taglib>
<taglib-uri>
http://www.yourcompany.com/yourTagLibrary
</taglib-uri>
<taglib-location>
/WEB-INF/yourTagLibrary.tld
</taglib-location>
</taglib>
...
</web-app>
security-constraint
The security-constraint element is used to associate security constraints with one
or more Web resource collections such as a security role and user roles that should
be permitted access to this resource collection.
Element
<!ELEMENT security-constraint (display-name?,
web-resource-collection+, auth-constraint?,
user-data-constraint?)>
<!ELEMENT auth-constraint (description?, role-name*)>
<!ELEMENT web-resource-collection (web-resource-name,
description?, url-pattern*, http-method*)>
<!ELEMENT user-data-constraint (description?,
transport-guarantee)>
Example
<web-app>
...
<security-constraint>
<web-resource-collection>
<web-resource-name>All Users Allowed Area
</web-resource-name>
<url-pattern>/allowed/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
</security-constraint>
...
</web-app>
login-config
The login-config element is used to configure the authentication method that
should be used, the realm name that should be used for this application, and the
attributes that are needed by the form login mechanism.
Element
<!ELEMENT login-config (auth-method?, realm-name?,
form-login-config?)>
Example
<web-app>
...
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Authentication Servlet</realm-name>
</login-config>
...
</web-app>
security-role
The security-role element contains the definition of a security role. The definition
consists of an optional description of the security role, and the security role name.
Element
<!ELEMENT security-role (description?, role-name)>
Example
<web-app>
...
<security-role>
<description>
This role includes all customers who have a credit
line with us based on at least one previous purchase.
</description>
<role-name>customer</role-name>
</security-role>
...
</web-app>
<web-app>
String value =
getServletContext().getInitParameter("name");
<context-param>
<param-name>webmaster</param-name>
<param-value>[email protected]</param-value>
<description>
The EMAIL address of the administrator to whom
questions and comments about this application
should be addressed.
</description>
</context-param>
<listener>
<listener-class>yourPackage.YourListener
</listener-class>
</listener>
http://localhost:8080/{context-path}/servlet/{classname}
<servlet>
<servlet-name>CustomerSupport</servlet-name>
<servlet-class>yourPackage.CustomerSupport
</servlet-class>
</servlet>
<servlet>
<servlet-name>Authentication</servlet-name>
<servlet-class>yourPackage.Authentication
</servlet-class>
<security-role-ref>
<role-name>alias</role-name>
<role-link>tomcat</role-link>
</security-role-ref>
</servlet>
<servlet>
<servlet-name>Store</servlet-name>
<servlet-class>yourPackage.Store</servlet-class>
<init-param>
<param-name>itemCount</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--
Define mappings that are used by the servlet container to
translate a particular request URI (context-relative) to a
particular servlet. The examples below correspond to the
servlet descriptions above. Thus, a request URI like:
http://localhost:8080/{contextpath}/graph
http://localhost:8080/{contextpath}/saveCustomer.do
<servlet-mapping>
<servlet-name>CustomerSupport</servlet-name>
<url-pattern>/CustomerSupport</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Authentication</servlet-name>
<url-pattern>/Authentication</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Store</servlet-name>
<url-pattern>/commerce/store</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<error-page>
<exception-type>java.lang.ArithmeticException
</exception-type>
<location>/ErrorPage06</location>
</error-page>
<taglib>
<taglib-uri>
http://www.yourcompany.com/yourTagLibrary
</taglib-uri>
<taglib-location>
/WEB-INF/yourTagLibrary.tld
</taglib-location>
</taglib>
<security-constraint>
<display-name>Example Security Constraint
</display-name>
<web-resource-collection>
<web-resource-name>Protected Area
</web-resource-name>
<!-- Define the context-relative URL(s)
to be protected -->
<url-pattern>/jsp/security/protected/*
</url-pattern>
<!-- If you list http methods,
only those methods are protected -->
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<!-- Anyone with one of the listed roles
may access this area -->
<role-name>tomcat</role-name>
<role-name>role1</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Authentication Servlet</realm-name>
</login-config>
<security-role>
<description>Security role we are testing for
</description>
<role-name>tomcat</role-name>
</security-role>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Your Web application will have errors; all software does. The servlet specification
addresses the need to handle errors. The first part of this objective addresses how
the deployment descriptor handles exceptions. The following snippet shows you how
to use the error-page element, which defines which resource the container should
use for a given exception.
<web-app>
<error-page>
<error-code>404</ error-code>
<location> /404.html </location>
</error-page>
</web-app>
With this definition, the client will get the 404.html page if it requests a page that
the container decides isn't available.
You can accomplish the same thing a little more dynamically with the
RequestDispatcher. You can forward a request to an error page easily like so:
ServletContext context = getServletContext();
dispatcher = context.getRequestDispatcher(
"/errors/error.jsp");
dispatcher.forward(request,response);
Although this is more dynamic, it ignores all kinds of rules for good practice. It would
be better to use the error-page element most of the time but forward to an error
page with the RequestDispatcher on occasion.
You can also specify the exception handling declaratively in the deployment
descriptor. You do this with the error-page element and the exception-type
subelement like so:
<web-app>
<error-page>
<exception-type> javax.servlet.ServletException
</exception-type>
<location>/servlet/ErrorDisplay</location>
</error-page>
</web-app>
This is a good practice as it makes the intention explicit for your Web application as
opposed to relying on defaults.
• Authentication, authorization
• Data integrity
• Auditing
• Malicious code
The security issues are ever present in software, and more so for Web applications
because you are exposing part of your machinery to the wild wild Internet. Sun
made a big effort to make Java secure, whether as a standalone or Web application.
This objective is really just a matter of a few definitions. The following list defines
each of the items in the objective:
• Data integrity. The means used to prove that information has not been
modified by a third party while in transit. The data is really what was sent.
• Auditing. Maintain a record of Web application activity. For example, you can
log resource accesses including times and requester IP and ID. This usually
involves a log somewhere.
• Web site attacks. An overt attempt to compromise your Web site. The most
popular attack is the denial-of-service attack where the attacker floods the
server with requests, reducing its capacity to service legitimate requests.
There is no end to the imagination of those who can't compete within society's rules.
You should design your Web application to withstand at least a minimum level of
attack, which is sometimes just an accident, or so we like to hope.
Authentication Types
6.3 Given an authentication type: BASIC, DIGEST, FORM, and CLIENT-CERT,
identify the correct definition of its mechanism.
As mentioned previously, authentication is the mechanism that makes sure you are
really you. Somehow, the Web client has to prove to your Web application its
identity. There are four ways to do that including HTTP Basic, HTTP Digest, HTTPS
Client, and Form Based authentication.
The following list defines each of the authentication types in the objective:
Chapter Summary
There are many aspects to deploying an application. The two major concerns are
what directories to use and what pieces comprise the application. The deployment
descriptor gives you a way to clearly define these aspects of your Web application.
This chapter described all the objectives associated with the deployment descriptor
on the SCWCD exam.
KEY TERMS
• Web application
• Authentication, authorization
• Security constraint
• Tag library
A1: A Web application is a collection of servlets, HTML pages, classes, and other
resources that make up a complete application on a Web server. It can be bundled
and run on multiple containers from multiple vendors. See "Introduction."
2:How is the WebApp deployment descriptor used?
A2: Remember that the deployment descriptor of a Web application is the web.xml file.
It defines many aspects of the Web application. See "Web Application and Web
Archive Structure."
3:What types of client authentications are there?
A3: There are four types of authentication, namely, BASIC, DIGEST, FORM, and
CLIENT-CERT. See "Authentication Types."
4:Why would you use a WAR file?
A4: You use a WAR file because Web applications can be packaged and signed into a
Web ARchive format (WAR) file using the standard Java Archive tools. When
packaged into such a form, a META-INF directory will be present that contains
information useful to Java Archive tools. See "Web Application and Web Archive
Structure."
5:How can you handle exceptions in a Web application?
A5: Given a set of business logic exceptions, you can configure the deployment
descriptor to handle each exception, you can use a RequestDispatcher to forward
the request to an error page, and you can specify the handling declaratively in the
deployment descriptor. See "Web Application Exceptions."
Exam Questions
1:Which two statements apply to the following code snippet? (Choose two.)
<servlet>
<servlet-name>
testServlet
</servlet-name>
<servlet-class>
myPackage.MyTestServlet
</servlet-class>
</servlet>
A. It is a mapping between a servlet name and the fully-qualified name of
the servlet class.
D. It uses SSL.
A2: C and D. This is end user authentication using HTTPS (HTTP over SSL). This
mechanism uses public key encryption that requires the user to possess a Public
Key Certificate (PKC). This is the highest level security of the four here. See
"Authentication Types."
3:Which directory is the location for myApp.jar?
A. /WEB-INF/
B. /WEB-INF/classes/
C. /WEB-INF/lib/
D. /
A3: C. The jar files go in the /WEB-INF/lib/ directory. See "Web Application and Web
Archive Structure."
4:In which two elements can you define initialization parameters?
A. servlet
B. context-param
C. welcome-file
D. login-config
A4: A and B. The initialization parameters are defined in both the context-param
and the servlet elements of the Web deployment descriptor. See "Deployment
Descriptor Elements."
5:Which three of the following are elements of the Web Application Descriptor?
A. servlet
B. context-param
C. listener
D. error
A5: A, B, and C. All of these are elements except there is no error element. It
should have been error-page. See "Deployment Descriptor Elements."
6:What is the configuration that the deployment descriptor uses to handle each
exception?
A. error-page
B. exception
C. error
D. exception-page
A6: A. The error-page element, which defines what resource the container should
use for a given exception.
<web-app>
<error-page>
<error-code>404</ error-code>
<location> /404.html </location>
</error-page>
</web-app>
See "Web Application Exceptions."
7:What is the deployment descriptor file named?
A. server.conf
B. server.xml
C. web.xml
D. web.conf
A7: C. web.xml is the deployment descriptor file. See "Web Application and Web
Archive Structure."
8:Which directory is the location for Web application class files?
A. /WEB-INF/
B. /WEB-INF/classes/
C. /WEB-INF/classpath/
D. /META-INF/classes
A8: B. You place your servlets and utility classes in /WEB-INF/classes/. See "Web
Application and Web Archive Structure."
9:What does the security-role element do?
A. /WEB-INF/
B. /WEB-INF/classes/
C. /WEB-INF/lib/
D. /
A10: A. web.xml is the deployment descriptor file in /WEB-INF/web.xml. See "Web
Application and Web Archive Structure."
11:Which of the following best defines authentication?
A. The means used to prove that information has not been modified by a
third party while in transit.
A. This is access control where it defines who can interact with what
resources.
<servlet-mapping>
<servlet-name>CustomerSupport</servlet- name>
<url-pattern>/CustomerSupport</url- pattern>
</servlet-mapping>
A. It defines how you refer to a given servlet in code.
B. It is a subelement of <servlet>.
D. It is a subelement of <webapp>.
A13: C and D. When a request is received by the container it must determine which
servlet should handle it. Using the deployment descriptor you can map certain
paths (aliases) to a specific servlet. You define this mapping with the servlet-
mapping element. The alias is appended after the context root in an HTTP
requesst URL. See "Deployment Descriptor Elements."
This chapter covers the following Sun-specified objectives for the "Design Patterns"
section of the "Sun Certified Web Component Developer For J2EE Platform" exam:
13.1 Given a scenario description with a list of issues, select the design
pattern (Value Object, MVC, Data Access Object, or Business Delegate) that
would best solve those issues.
• Value Object
• MVC (Model-View-Controller)
• Business Delegate
• Front Controller
• Have you been to the bookstore lately? New books on patterns are added
weekly. The growing interest is about a new approach to designing software
that is fast becoming a darling of the industry. I like the academic nature of
the topic (this should come first), but some of the books on this subject are
impractical. After all, most of the buyers now are programmers, so they need
direct help with code. This chapter endeavors to demonstrate how to apply
the theory to practice.
OUTLINE
Introduction
Value Object
Is
Is Not
Analogy
Problem
Responsibility
Context
Motivation or Forces
Applicability
Solution
Consequences
Known Uses
Related Patterns
References
Is
Is Not
Analogy
Problem
Responsibility
Primary Activity
Context
Motivation or Forces
Applicability
Solution
Consequences
Known Uses
Related Patterns
References
Business Delegate
Is
Is Not
Analogy
Problem
Responsibility
Primary Activity
Context
Motivation or Forces
Applicability
Solution
Consequences
Known Uses
Related Patterns
References
Model-View-Controller (MVC)
Is
Is Not
Analogy
Problem
Responsibility
Primary Activity
Context
Motivation or Forces
Applicability
Solution
Consequences
Known Uses
Related Patterns
References
Front Controller
Is
Is Not
Analogy
Problem
Responsibility
Primary Activity
Context
Motivation or Forces
Applicability
Solution
Consequences
Known Uses
Related Patterns
References
Sample Pattern
Name
Summary
Is
Is Not
Analogy
Problem
Responsibility
Primary Activity
Context
Motivation or Forces
Applicability
Solution
Consequences
Known Uses
Synonyms
Glossary
Related Patterns
References
Chapter Summary
Review Questions
Exam Questions
STUDY STRATEGIES
• As you read through this chapter, you should concentrate on the following key
items:
• The best way to study these items is to read through the chapter and work
each of the examples. Then answer the review and exam questions. If you
get an answer wrong, study your answer and the correct answer and make
sure that you understand the differences between them.
Introduction
In this chapter you'll learn about design patterns, a new approach to designing
software that Sun is advocating engineers use for Java, especially J2EE. There is no
API to know for this exam area. Instead, you'll learn the basics of design patterns so
that you can use this knowledge to complete this section of the exam. Hopefully, this
chapter will be so useful you'll apply it to your development assignments as well.
Whether you are a software manager, designer, engineer, or student, design patterns
are the new foundation upon which to design and build software projects. This
chapter helps you bridge the gap between the highly abstract GoF presentation,
including the many books based on it, and the real-world challenges of writing code.
If used as Sun suggests, and this chapter echoes, patterns become a core asset of
any software shop. Patterns show the developer how to solve problems created by
market and technology forces in a systematic way.
This chapter assumes you've read the previous chapters first and that you are very
familiar with object-oriented programming, including the popular UML diagramming
notation. This chapter describes the four pattern solutions named in the objectives.
It also discusses patterns beyond the four. This bonus section is optional, but will
probably help you understand the first four better. Certainly, you will encounter many
more throughout your career as you address enterprise design needs.
While Alexander was thinking buildings and foundations, it became clear to many
that his design patterns were abstract enough to be useful elsewhere. That is when
the Gang of Four, as Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
are now known, applied his patterns to software in their classic Design Patterns:
Elements of Reusable Object-Oriented Software (1995, Addison-Wesley). It took a
while, but the GoF have started a ground swell. There are now dozens of books, and
many more on the way, about design patterns.
Design patterns are often defined as "a solution to a problem in a context." This falls
short of the abstract definition that experts prefer. Suppose you have an object that
makes copies of files. What is the design pattern? We don't know yet, so let's throw
in an object that copies the content of one text box to another. There is something
about the copying that is the same between the two objects. Neither the files nor the
text boxes differ, but the copying is the same. So, the sameness is copying. By itself
this isn't a pattern, but we are on the way to finding one.
What are design patterns? Sun defines them in the following way: "A design pattern
describes a proven solution to a recurring design problem, placing particular
emphasis on the context and forces surrounding the problem, and the consequences
and impact of the solution." It is like the old guy who doesn't say much. There is
commotion in the car design room over how they can fit the chromed company logo
on the back of the trunk lid as close to the key hole as possible. They are trying just
above, below, then perhaps they go wild and go vertical… The old guy grows weary
so he comes over to the young guns and, without a word, drills a hole in the logo
and places the logo hole exactly centered over the key hole so that you can just stick
a key into it. It doesn't look bad, either. They stare, and then nod in unison. From
years of experience of doing back ends of cars, he knows that is the best way to
handle it. It's a pattern the old guy knows, and now the kids just learned it.
Design Pattern Elements
There are many ways to define a pattern, but the classical way is to describe its
elements, or the aspects of a pattern. There are several lists of elements in the
literature today. I will use a dolled-up version of the GoF's approach.
All of them center on three base elements, namely, context, problem, and solution.
The following are their definitions:
• Problems are the so-called forces, such as marketing and technological forces,
that occur in this context.
The design pattern is not only these three, but the relationship between the three
and the formal language that describes the whole business. That is a lot of heady
language that doesn't seem to touch earth and is certainly not on the exam. I'll say
more on this at the end of the chapter if you care to regress to some intriguing
musings. Presently, I'll list the elements.
Remember that context, problem, and solution are at the core. The remainder is my
way of expanding these three in the hope of providing a few more handles to grab as
a way to understand the essence of a given pattern. The purist will gawk, but so
what, they aren't taking the exam. The pattern elements used in this book are as
follows:
• Intent [or goals and constraints]— These are the goals and objectives the
pattern should reach within the given context.
• Primary Activity— Okay, a pattern is wonderful and all, but it has one thing it
has to get done.
• Context— The conditions and environment in which the problem and its
solution recur. In other words, where should you consider and apply this
pattern?
• Motivation or Forces— Why bother? These are the forces that affect the
context and the reason why you would use a pattern. This tells you about the
advantages the pattern offers.
• Applicability— Which kinds of situations are good candidates for this pattern.
• Solution
o Pseudo Code— This is pseudo-code to help you see how you might
actually implement the pattern, to reduce the concept to practice.
• Consequences— This describes the result of using the pattern, the final state
of the system. There are good and bad consequences of applying the pattern.
It may solve one problem, but give rise to a new one.
• Known Uses— This tells you one or more examples of how this pattern is
being used.
• Related Patterns— This names other patterns that are related by context,
solution, or consequences. The related pattern may solve the same problem
in another way or share the same context, but resolve different forces.
• Reference— This points you to a resource that will provide more material on
the pattern.
The following five definitions list more than you need to know about each one.
However, it's hard to understand these patterns without this kind of detailed
explanation. The end of the chapter questions represent what you can expect on the
exam, but read these five definitions to get a feel for what patterns are in general
and to understand these five in particular.
Value Object
This pattern provides the best way to exchange data across tiers or system
boundaries, especially when there is network communication involved. This is a
pattern that solves performance issues around network latency.
Is
This pattern is an object that encapsulates a set of values (namesake) that is moved
across the boundary so that attempts to get the values of those attributes are local
calls.
Is Not
This pattern is not a concrete object. You wouldn't use it to create, say, a car object.
You could use it to hold values about a car though, such as the color and model of
the car.
Analogy
This would be like placing several letters in a box to be mailed once a week instead
of mailing the letters separately. The box is mailed once. When the box arrives, the
mail carrier can just reach in the box for the next letter; she doesn't have to go back
to the origin, which would take a long time. The problem is she doesn't know if the
sender is still at the originating address anymore since the box has been delivered
for some time.
Problem
In J2EE, server-resident business applications often use session beans and entity
beans. The session beans are responsible for functionality that is involved in one-to-
one transactions with the client. Contrast that with the entity beans, which are
intended to handle persistent data. So, the client will make many calls to the session
bean to get data. That represents a lot of traffic, potentially, to and from a remote
location because the bean may be at a server there. Likewise, the session bean may
make many calls to the entity bean getting and setting attributes. The Value Object
pattern encapsulates the data fields of an entity bean; VO has nothing to do with
session beans (except that it is usually a session method call that returns a VO,
instead of a remote entity reference). By the way, this is EJB terminology, which is
not on the exam—this is just an example.
This activity is inefficient. We need a way to eliminate all these potential network
calls reducing overhead and providing a more direct access approach.
Responsibility
This pattern provides a mechanism to exchange many remote calls to local, direct
calls.
Primary Activity
Used to collect remote data into an object that is sent to the client, so now the client
makes local calls to get values rather than remote ones.
Context
Multi-tier applications that need to exchange sets of data between the client and
server often.
Motivation or Forces
• J2EE applications often use enterprise beans. All calls to these beans are
performed via remote interfaces to the bean due to Java's architecture. This
introduces overhead.
• The frequency of reads is greater than updates because the client gets the
data from the business tier for presentation.
• The client usually needs a set of data, not just one attribute.
• Client calls to enterprise beans accessed over the network affects WebApp
performance because of the sum of network latency of multiple attribute
access to the entity bean.
Applicability
This pattern is useful when you need a collection of data from a remote source or,
more likely, when a client has to make several calls for data from entity beans.
Solution
• Strategy— Use a Value Object to encapsulate a collection of data so that it
takes only one call to get or set the collection.
// public members
public int customerID;
public int accountNumber;
public int OrderNumber;
public float OrderAmount;
// default constructor
public CustomerOrder() {}
return success;
}
}
Consequences
• Simplifies Entity Bean and Remote Interface— Sun suggests using getData()
and setData() methods on certain entity beans as a way to get and set a
value object containing the set of attribute values. Calling the getData()
method once replaces multiple calls to get methods. Likewise, the setData()
method replaces many set calls.
• Using this pattern transfers a set of values in one method call improving
overall performance, especially over the network. It represents coarse versus
fine-grained interfaces.
• The client can update, delete, and read the values that are now local at will.
When done, it can update the data source in one call. However, there may be
a problem with synchronization as the other clients won't know about the
changes until the update call. In the case of updates, there can be two
conflicting update calls by two clients, so this must be synchronized somehow.
Known Uses
The ResultSet of JDBC is a collection of data returned from the data source resulting
from a query. The data is now local in the ResultSet object so all calls to it are local
rather than many calls to the data source directly.
Related Patterns
• Aggregate Entity that uses Value Object to get data across tiers.
• Value List Handler is another pattern that provides lists of value objects
constructed dynamically by accessing the persistent store at request time.
• Value Object Assembler builds composite value objects from different data
sources. The data sources are usually session beans or entity beans that may
be requested to provide their data as value objects.
References
http://developer.java.sun.com/developer/restricted/patterns/ValueObject.html. This
page is only available to registered members of the Java Developer connection.
Is
This pattern is an object that encapsulates a set of behaviors for accessing
databases, files, and other resources. This way you have only one API to deal with
rather than a different one for every type of resource.
Is Not
This is not a pattern for a resource itself. It isn't a way to build a database or file
manager, in other words.
Analogy
This is like using an ATM machine. The same interface will fetch the information
requested from the back end, even though the bank changed database products the
previous week so, of course, it reports a negative balance.
Problem
Applications often need to use persistent data. This data persists in many forms such
as files, relational databases, XML storage, and other types of repositories. All these
stores have different APIs. Interfacing with so many APIs presents a problem when
designing clients.
Responsibility
This pattern provides a uniform API to any persistent data storage.
Primary Activity
Getting and setting data from and to a permanent data source.
Context
Access methods to data vary between types of storage and vendor.
Motivation or Forces
Various parts of an application require access to persistent stores like databases and
files. The APIs are inconsistent between types of stores and even between different
vendors of the same type of storage. There needs to be a layer that has a uniform
API to access these disparate data sources.
Applicability
Any application that requires access to several data source types or even an
application that accesses only one, but may switch in the future. The SQL is
encapsulated in the method. That way if the SQL or datasource change, the layers
above won't because the API remains constant.
Solution
• Strategy— Use this pattern to design a Data Access Object that abstracts the
access API to various data sources.
• Pseudo-code— The example shown in Listing 11.2 is small. The real class
would likely have more SQL, but it does represent an interface that defines
the API DAO for a single entity and uses an Abstract Factory to create the
necessary implementation objects at runtime. Listing 11.2 is an example of
this pattern.
/**
* This class is an example of DAO because
* it encapsulates the SQL calls made by other objects.
* This layer maps the relational data stored in the
* database to the objects needed by another layer.
*/
public class CustomerDAO
{
private Connection con;
Consequences
• Clients and components can now access data with the same API, which makes
the variety of sources transparent and reduces complexity.
Known Uses
At one level, JDBC uses an Abstract Factory technique to provide one API to many
databases and types of files; the very essence of this pattern. However, the
emphasis Sun places on this pattern is that of encapsulating the SQL so the
implementation of actually querying the database is hidden from the next layer.
Related Patterns
• Abstract Factory [GoF]: Sun uses this factory for data access object strategy.
They base it on the abstract factory method.
References
http://java.sun.com/blueprints/patterns/DAO.html
Business Delegate
This pattern reduces the dependency between tiers. It is an attempt to make tiers
interchangeable so one can access the services of any other.
Is
This pattern is a proxy that hides the complexity of remote service lookup and error
recovery. It makes it easier to communicate requests and results from one layer to
another.
Is Not
This is not a pattern for a layer itself. It isn't a way for you to create a business logic
component or structure. Rather, it is an interface to a tier so that you can change the
underlying components and not disturb the presentation tier.
Analogy
This pattern is like an ambassador. Like all good ambassadors, it can relay a
message from the host country to any other.
Problem
Whenever there is a dependency on a remote service, the likelihood of change
between the caller and called increases. How can you reduce the chances of the layer
depending on the remote service breaking should the remote service change? This
pattern helps protect the local layer from changes made to the remote service.
Perhaps the presentation tier interacts directly with a remote business logic layer.
What if the business services change and the old API becomes invalid? If this
happens the presentation tier will break.
Responsibility
This delegate is the proxy between the local layer and the remote service layer. It is
responsible for reliably allowing the front layer to access the remote service.
Primary Activity
This pattern matches presentation component calls to the correct business tier
methods.
Context
The current approach to multi-tier systems is to couple the presentation tier directly
to the entire business service API; sometimes this coupling is made across a
network.
Motivation or Forces
• Presentation-tier clients (including devices) need access to business services.
• This pattern adds more work to building a system. Is this extra layer really
necessary?
Applicability
Large systems change components often. There is often a change in the business tier
that breaks the access portion of clients.
Solution
• Strategy— Sun says, "Use a Business Delegate to reduce coupling between
presentation-tier clients and business services. The Business Delegate hides
the underlying implementation details of the business service, such as lookup
and access details of the EJB architecture."
• Sample code— Look up Java API for XML Messaging ("JAXM") and its use of
XML messaging using SOAP. This reference will show you a very good
example of JAXM using SOAP, which acts like a Business Delegate pattern
(http://java.sun.com/webservices/docs/ea2/tutorial/doc/JAXM.ws.html).
Consequences
• Caching is always good between parts that exchange a lot of data.
• This pattern changes the interface with the intent of making the API more
stable from the presentation tier perspective.
• This pattern will now handle any exceptions, whether from the business tier
itself or from the plumbing between it and the requester.
• This pattern isolates the presentation and the business tiers from each other
by adding a director between the two, making it is easier to manage changes
on either side.
Known Uses
• B2B systems usually employ an XML exchange for communicating between
disparate systems.
Related Patterns
• Service Locator Pattern— This pattern provides a common API for any
business service lookup and access code.
• Adapter Pattern— You can use the Adapter pattern to provide coupling for
disparate systems.
References
java.sun.com/blueprints/patterns/BusinessDelegate.html
Model-View-Controller (MVC)
The Model-View-Controller architecture compartmentalizes the data and business
logic (model) from the presentation (view) from the user action interpreter
(controller). This pattern is the hardest on the exam. The idea is closely related to
the recent move from two-tier to three-tier architectures. This arrangement allows
multiple views to share the same enterprise data model.
Is
This pattern is a clear functional separation of roles. It is a formalization of the data-
business-presentation movement that dominated three-tier architectures over the
last decade.
Is Not
This pattern is very abstract. It is not simply a front end to a datasource.
Analogy
This would be like an automobile. The speed of a car is affected by the accelerator
pedal (Controller), the speed is shown by the speedometer (View), and the speed is
manifested by the engine (Model).
Problem
Different views of the same data are a common need. Conversely, the same client
needs access to different models.
Responsibility
This pattern carefully manages communication between the client and model data
and functionality. It must allow changing the client or changing the model with
minimal impact on the system.
Primary Activity
This pattern decouples views from data and business logic; MVC interjects a
controller between them, which interprets user actions into operations on the
business logic and the selection of the next view to send to the user.
Context
An application is expected to support varying client and business logic tiers.
Motivation or Forces
• Various clients and data models are being developed. These two tiers need to
talk to each other.
• The same enterprise data will be accessed by different views: for example,
HTML, WML, JFC/Swing, and XML.
• The same enterprise data will be accessed (requested, modified, and deleted)
from various actions (HTML links, JFC/Swing events, SOAP XML calls).
Applicability
Although the primary purpose of MVC is for building UIs, it can be used to establish
an analogous notification protocol between non-visual objects. The
Observer/Observable objects in java.util were designed with this pattern in mind.
Solution
• Strategy— Use the Model-View-Controller architecture to decouple
presentation from core data access functionality. Also, this pattern allows you
to control the communication between them so that multiple views can see
the same enterprise data model, or multiple data models can present to the
same view. So, the types of Web components used in the WebMVC pattern
are these: servlet as Controller/Dispatcher, JSP pages as Views, and Java
classes (or EJBs) as Model.
• Pseudo-code— MVC is used for many things. For example, it has been used
for Swing to build user interfaces where Sun uses the model as the underlying
logical representation, the view as the visual representation, and the
controller as the part that handles user input. When a model changes (the
user modifies text in a text field), it notifies all views that depend on it
(listeners). This allows you to present a single set of data in list, table, or
simple text presentations. As you update the data model, the model notifies
both views and gives each an opportunity to update itself. In this architecture,
the controller determines which action to take when the user alters the model
(types text into field). Please see:
http://developer.java.sun.com/developer/onlineTraining/GUI/Swing2/shortcou
rse.html#JFCMVC.
Consequences
• Clients access a controller that accesses the model instead of the data
directly.
• It is easier to break a project into pieces because both the view and model
developers are targeting the controller API.
Known Uses
Java uses MVC for JFC/Swing. Also, Struts and Velocity use this pattern as their
underlying framework.
Related Patterns
• A very high-level pattern, whereas the others on the exam are lower-level.
This one has few related patterns.
References
http://java.sun.com/blueprints/patterns/j2ee_patterns/model_view_controller/index.
html
Front Controller
This pattern presents one entry point to a Web site or service. It provides a
centralized entry point that controls and manages Web request handling. It
eliminates the dependency of the user on a direct resource. Suppose you wanted to
get the latest version of the servlet specification. You would be better off going to a
central page that presents options that change over time than bookmarking the
servlet specification directly as that will break quickly.
Is
This pattern is a presentation controller that allows the resources to change without
breaking all the bookmarks to a given resource. Many sites use this. For example,
Microsoft often changes the content in its excellent developer's MSDN library.
However, there is front end for it that rarely changes. This way, you can bookmark
that front-end URL and not worry about what they do behind it.
Is Not
This is not a pattern for a data storage viewer. It isn't a way for you to control data
retrieval. Rather, it is a steady interface to the underlying Web resources that behave
as the presentation tier.
Analogy
This pattern is like a travel agent. On every trip you start by stopping at the agency.
You tell the agent where you want to go and she will take care of the arrangements.
The actual flight, train, bus, and hotel details change between trips, but she always
gets there.
Problem
When the user accesses resources directly without going through a centralized
mechanism, the resource may have moved. Also, each view is on its own and
required to provide its own system services. Lastly, each view has to provide
navigation, but this is a problem as it doesn't know about the context or the global
site.
Responsibility
This controller must delegate the request to the proper resource and view.
Primary Activity
This pattern matches the correct resource to the request.
Context
Simplified Web sites expose all its resources directly. As a site grows, there comes a
time when it is better to decouple the navigation from the resources. There needs to
be a controller that manages the requests and decides which resource best satisfies
the request.
Motivation or Forces
• It is better to have a central controller allocate shared resources rather than
have individual resources fend for themselves independently.
• This pattern adds only a little more work to building a Web site at first.
Solution
• Strategy— Sun says, "Use a Controller as the initial point of contact for
handling a request. The Controller manages the handling of the request,
including invoking security services such as authentication and authorization,
delegating business processing, managing the choice of an appropriate view,
handling errors, and managing the selection of content-creation strategies."
• Sample code— This pattern can be used to centralize request processing and
view selection. For example, the class MainServlet is the front controller for
Sun's Java Pet Store sample application Web site. All requests that end with
*.do are sent through the MainServlet for processing. Please see
http://java.sun.com/blueprints/code/jps11/src/com/sun/j2ee/blueprints/petst
ore/control/web/MainServlet.java.html.
Consequences
• Caching is always good between parts that exchange a lot of data.
• This pattern changes the interface with the intent of making the API more
stable from the presentation tier perspective.
• This pattern will now handle any exceptions, whether from the business tier
itself or from the plumbing between it and the requester.
• This pattern isolates the presentation and the business tiers by adding a
mediator between the two, making it easier to manage changes on either
side.
Known Uses
• Servlet Front Strategy— This pattern is implemented as a servlet, which
manages the aspects of request handling that are related to business
processing and control flow. Because this strategy is not specifically related to
display formatting, it is a bad idea to implement this component as a JSP
page.
• Logical Resource Mapping Strategy— In this case users request logical names
rather than physical locations. This way the physical location can be mapped
to the logical names dynamically, say, in a database or XML document.
Related Patterns
• View Helper Pattern— The Front Controller is combined with the View Helper
pattern to provide containers for factoring business logic out of the view and
to provide a central point of control and dispatch. Logic is factored forward
into the front controller and back into the Helpers.
• Dispatcher View— The Dispatcher View pattern is the result of combining the
View Helper Pattern with a Dispatcher, in coordination with the Front
Controller pattern.
References
http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
I hope this extra section will help you understand and apply Design Patterns to your
software projects, whether you are a software manager, designer, engineer, or
student. It bridges the gap between the highly abstract GoF presentation, including
the many books based on it, and the real-world challenges of writing code. If used as
this chapter suggests, patterns become a core asset of any software shop. This
section of the chapter shows you how to solve problems created by market and
technology forces in a systematic way.
One field of study precedes and is more mature than patterns. You can look to it for
help with patterns. That field is topology. It says a donut and coffee cup are the
same even though I eat a donut, but not a coffee cup (drunk friends don't count).
Topologists ignore this difference. What you consider and what you don't determines
how you think about something. Topology is an excellent place to turn to if patterns
are still foggy. Don't worry, topology is worse so you'll forget your pattern
headaches.
Overlooking the context and forces aspects of patterns, how are they like topology?
More to the point, how do we define a pattern at all? One way is to use the concept
of invariance. A pattern is something that doesn't vary when something else
changes. Take an algebraic formula A * B = C. This formula rigorously defines a
relationship between variables (elements and forces in patterns). The values of A, B,
and C vary, but the relationship between them is fixed. The defined relationship is
the pattern.
Back to topology, the donut and coffee cup have a hole. No matter how much you sit
on your donut it still has a hole. Topology doesn't care if you stretch and twist, but
you can't tear. If your cup was made of plastic then you could warm it gently and,
with a little effort, form it into a donut where the handle now becomes the center
hole. Likewise, before you cook it, you could take a donut shaped dough ring and
shape it like a cup where the center hole becomes the handle. Then cook it. So, the
hole is invariant and makes the two equal topologically.
In software, what is invariant? The rules for making an interface that consistently
accesses resources (that is, the database) should be invariant. These rules, and their
explicit description, represent a pattern. So far, no one has determined how to
rigorously define aspects of software so that we could declare a formal language to
describe patterns. UML is a recent improvement toward this end.
I would like to define patterns as a named design strategy and model outlining
solutions that address a set of responsibilities in a popular context. It's a guide that
should survive functional changes handled at the implementation level. The set of
responsibilities recurs; it is not a rare situation and addresses many circumstances at
once. The context is popular, not an obscure one, which insures that it is worth the
effort. Patterns give a rationale for their context of applicability.
Good design starts with requirements (wish list), moves to responsibilities (a set of
objects that fulfill requirements), and ends with functionality (behavior within objects
that meets responsibilities). The requirements are given to the designer while the
functionality is in the details of an implementation. Between these are the
responsibilities—the focus of patterns.
Real patterns are between all these. For example, the Façade Pattern tells you how
to design one interface that acts as a mediator for many others. It reduces to one
the number of interfaces a client faces, rather than many. The Façade defines a
parent interface, making a subsystem easier to use. The Façade has fewer
responsibilities than Windows and MyCompany Customer Manager. It has a context
encountered by more programmers than MyCompany Customer Manager. It is bigger
than Choice. Finally, it is useful because it is easily applied to many programming
assignments.
Sample Pattern
The following pattern is of my own definition. I have many of them, but they are not
proven, so be careful before you try to use this one. However, I offer it to you as an
example of how approaching software design through patterns can make sharing
ideas more efficient, clearer, and easier to test.
Name
Transcoder
Summary
Defines how to convert a message in one code to another (HTML to WML, ASCII into
XML, XML-XSL-HTML).
The need to change how we encapsulate messages, change how they are encoded,
occurs often in software engineering. We want a clear plan on how to achieve these
conversions to avoid problems later. Also, we want to canonize what is common
between converting HTML to WML and XML-HTML, indeed most code-to-code
conversions. Transcoding is a complicated process that can involve both mapping
tables and algorithmic mapping, so we need a concise blueprint.
Although translation is older (Sumerians needed to talk to the Acadians and later
Babylonians to Egyptians), transcoding is old also. From ancient times governments
needed a way to convert between number systems or accounting standards within
their own language. The most likely situation will involve XML where the input XML
has one schema and the output requires a different schema. Also, many scenarios
require conversion between XML and other encodings like ASCII and HTML.
Is
This pattern is simply a translator for code.
Is Not
Its focus is not formatting, although it may include formatting.
Analogy
Telegraph operator converts English into Morse Code.
Problem
Describes the design issues faced by the developer when translating a message
encoded one way into another code. One current problem is how to convert a
message in ASCII or XML to HTML.
Responsibility
Ensure meaning encoded one way completely transfers when encoded another way
and is recoverable.
Primary Activity
Code-to-code translation.
Context
Application clients need to exchange data with enterprise systems and with each
other.
Motivation or Forces
• Message consumers vary in their interpretation capabilities.
• Need to decouple code details from message handling, thus hiding the
underlying implementation details of the service, such as lookup and access.
SOAP and Web services are examples.
Applicability
Exchanges, message store and forward services, viewers.
Solution
• Structure. The structure is described in Figure 11.1.
/*
* set of XML business documents and their
* components by Commerce One Inc.
* http://www.xcbl.org/
*/
private static final int xCBL = 1;
/*
* ediML ANSI 4010 850 XML Message
* components by GE Global Exchange Services
* http://www.xml.org/xml/schema/90a9a94b/AN4850.DTD
*/
private static final int ediML = 2;
/*
* FedEx Trade Networks is XML mark-up to encapsulate
* all the information contained in EDI.
*/
private static final int FedEx = 3;
/*
* ebXML is a framework, not a spec for, say, invoices
* shown for interest. You could do ebXML to SOAP.
*/
//private static final int ebXML = 4;
/**
* Default constructor.
*/
public Transcoder() {}
/**
* Sets the source schema.
*
* @param sourceSchema Schema of source code.
*/
public void setSourceSchema(int originSchema)
{
this.sourceSchema = originSchema;
}
/**
* Sets the source code.
*
* @param source code to be translated.
*/
public void setSource(String origin)
{
//perhaps preprocess source
switch (sourceSchema)
{
case xCBL:
//do something with xCBL
break;
case ediML:
//do something with ediML
break;
case FedEx:
//do something with FedEx
break;
case ebXML:
//do something with ebXML
break;
default:
//do something else
break;
}
this.source = origin;
}
/**
* Sets the output code.
*
* @param outputSchema The schema to translate into.
*/
public void setOutputSchema (int outputSchema)
{
this.outputSchema = outputSchema;
}
/**
* Sets the output code.
*
* @param output The code string that was translated.
* This would be used internally by the reader.
*/
public void setOutput(String output)
{
//perhaps postprocess output
switch (outputSchema)
{
case xCBL:
//do something with xCBL
break;
case ediML:
//do something with ediML
break;
case FedEx:
//do something with FedEx
break;
case ebXML:
//do something with ebXML
break;
default:
//do something else
break;
}
this.output = output;
}
/**
* Set the Reader to be used for the Source.
*
* @param reader A valid Reader or the code.
*/
public void setReader(Reader reader)
{
this.reader = reader;
}
/**
* get the Reader to be used for the Source.
*/
public boolean translate()
{
//process source with reader, the real work
boolean successfullyRead Source = reader(source,
inputSchema, outputSchema);
if (successfullyRead)
{
output = reader.getTranslation();
} else
{
output = null;
}
return successfullyRead;
}
}
Consequences
• This pattern defines a family of transcoding algorithms.
Known Uses
The best example of this pattern is XSL. Its whole purpose in life is to convert one
XML schema into another.
Synonyms
translator, transcripter
Glossary
• Coupling— High probability that a change in one module will require change in
other modules.
Related Patterns
Strategy pattern. You could also have a factory of translators.
References
None.
Chapter Summary
In this chapter, you were introduced to Design Patterns, a fundamentally sound
approach to designing applications. For example, Swing GUIs are built with the
Model-View-Controller pattern. You learned how to think about patterns, the
problems they solve, and how they work. Finally, your familiarity with the four
patterns listed in the objectives will help you answer the related questions on the
exam.
KEY TERMS
• JFC/Swing architecture
• Design Patterns
• Model-View-Controller
• Value Object
• Front Controller
• Business Delegate
Apply Your Knowledge
Review Questions
A1: Sun says, "A design pattern describes a proven solution to a recurring design
problem, placing particular emphasis on the context and forces surrounding the
problem, and the consequences and impact of the solution." See "Design Patterns
Defined."
2:Give an example of a pattern used in Java.
A2: Design patterns abound in Java as Sun has made a point of using them in the
architecture of Java. For example, the Swing architecture uses MVC.
javax.swing.JComponent, which extends java.awt.Container, and uses the
Model-View-Controller pattern. See "Design Patterns Defined."
3:Where did patterns come from and who invented them?
A3: Alexander, a building architect, invented patterns and then GoF applied them to
software design. We have been refining the idea ever since. See "Introduction."
4:Why should you use patterns?
A4: Patterns formalize design strategy, which benefits from the knowledge and
experience of other people who understanding contexts, forces, and solutions and
the relationship among the three. See "Introduction."
5:What is the primary benefit of patterns?
A5: Good patterns are more reusable than code. See "Introduction."
Exam Questions
1:Which design pattern has as its primary responsibility to decouple presentation and
service tiers, and a central director?
A. Value Object
B. Composite View
C. Business Delegate
D. Model-View-Controller
A1: D. The Model-View-Controller pattern has as its primary responsibility to decouple
presentation and data/business logic tiers, by using a director or switchboard
between them. See "Model-View-Controller (MVC)."
2:Which design pattern has as its primary responsibility to exchange data between
tiers?
A. Value Object
Part II: Final Review
Fast Facts
Practice Exam 1
Practice Exam 2
Practice Exam 3
Study Tips
There are many ways to approach studying, just as there are many different types of
material to study. The following tips, however, should work well for the type of
material covered on the certification exam.
Study Strategies
Although individuals vary in the ways they learn, some basic principles apply to
everyone. You should adopt some study strategies that take advantage of these
principles. One of these principles is that learning can be broken into various depths.
Recognition (of terms, for example) exemplifies a more surface level of learning in
which you rely on a prompt of some sort to elicit recall. Comprehension or
understanding (of the concepts behind the terms, for example) represents a deeper
level of learning. The ability to analyze a concept and apply your understanding of it
in a new way represents an even deeper level of learning.
Your learning strategy should enable you to know the material at a level or two
deeper than mere recognition. This will help you do well on the exam. You will know
the material so thoroughly that you can easily handle the recognition-level types of
questions used in multiple-choice testing. You also will be able to apply your
knowledge to solve new problems.
An outline provides two approaches to studying. First, you can study the outline by
focusing on the organization of the material. Work your way through the points and
subpoints of your outline with the goal of learning how they relate to one another. Be
certain, for example, that you understand how each of the objective areas is similar
to and different from the others. Next, you can work through the outline, focusing on
learning the details. Memorize and understand terms and their definitions, facts,
rules and strategies, advantages and disadvantages, and so on. In this pass through
the outline, attempt to learn detail rather than the big picture (the organizational
information that you worked on during the first pass through the outline).
Research has shown that attempting to assimilate both types of information at the
same time seems to interfere with the overall learning process. To better perform on
the exam, separate your studying into these two approaches.
Next, determine whether you can apply the information you have learned by
attempting to create examples and scenarios on your own. Think about how or
where you could apply the concepts you are learning. Again, write down this
information to process the facts and concepts in a more active fashion. An obvious
way to do this for the Java exams is to create code and test it.
Pre-Testing Yourself
Pre-testing enables you to assess how well you are learning. One of the most
important aspects of learning is what has been called meta-learning. Meta-learning
has to do with realizing when you know something well or when you need to study
some more. In other words, you recognize how well or how poorly you have learned
the material you are studying.
For most people, this can be difficult to assess objectively on their own. Practice tests
are useful in that they reveal more objectively what you have learned and what you
have not learned. Use this information to guide review and further study.
Developmental learning takes place as you cycle through studying, assessing how
well you have learned, reviewing, and assessing again until you think you are ready
to take the exam.
You might have noticed the practice exams included in this book. Use them as part of
the learning process. The exam software on the CD-ROM also provides a variety of
ways to test yourself before you take the actual exam. By using the practice exams,
you can take an entire timed practice test quite similar in nature to that of the actual
certification exam.
You should set a goal for your pre-testing. A reasonable goal would be to score
consistently in the 90% range.
See Appendix E, "What's on the CD-ROM," for a more detailed explanation of the test
engine.
Exam Prep Tips
The Java 2 certification exams reflect the knowledge domains established by Sun.
The multiple-choice exams are based on a fixed set of exam questions. The
individual questions are presented in random order during a test session. If you take
the same exam more than once, you will see the same number of questions, but you
will not necessarily see the exact same questions.
The multiple-choice and essay certification exams also have a fixed time limit in
which you must complete the exam. The test engine on the CD-ROM that
accompanies this book provides time-limit exams.
Finally, the score you achieve on the multiple-choice exams is based on the number
of questions you answer correctly. If you are in doubt, guess. In addition, do not
dwell on any one question for too long. Exam time can be consumed very quickly.
• Take any of the available practice tests. Try the ones included in this book and
the ones you can create using the exam software on the CD-ROM.
• Take a deep breath and try to relax when you first sit down for your exam
session. It is important to control the pressure you might (naturally) feel
when taking exams.
• You will be provided with scratch paper. Take a moment to write down any
factual information and technical detail that you committed to short-term
memory.
• Carefully read all information and instruction screens. These displays have
been put together to give you information that is relevant to the exam you
are taking.
• Read the exam questions carefully. Reread each question to identify all
relevant details.
• Tackle the questions in the order they are presented. Skipping around will not
build your confidence; the clock is always counting down.
• Do not rush, but also do not linger on difficult questions. The questions vary
in degree of difficulty. Do not let yourself be flustered by a particularly difficult
or verbose question.
• Note the time allotted and the number of questions appearing on the exam
you are taking. Make a rough calculation of how many minutes you can spend
on each question and use this to pace yourself through the exam.
• Take advantage of the fact that you can return to and review skipped or
previously answered questions. Record the questions you cannot answer
confidently, noting the relative difficulty of each question, on the scratch
paper provided. After you have made it to the end of the exam, return to the
more difficult questions.
• If session time remains after you have completed all questions (and if you are
not too fatigued!), review your answers. Pay particular attention to questions
that seem to have a lot of detail or that involve code analysis.
• As for changing your answers, the general rule of thumb here is don't! If you
read the question carefully and completely and you thought that you knew
the correct answer, you probably did. Do not second-guess yourself. If, as you
check your answers, one clearly stands out as incorrectly marked, then
change it. If you are at all unsure, however, go with your first impression.
If you have studied and you follow the preceding suggestions, you should do well.
Good luck!
Practice Exam 1
Exam Questions
D. The log is noted and then pending requests get simple error returns.
A47: B. The container crash is disastrous. The destroy method, like init, is
called only once. It is called when taken out of service and all pending
requests to this servlet are done, including timeouts. destroy is not called if
the container crashes! You should log activity elsewhere when appropriate
because the destroy method is not called if the servlet container quits
abruptly (crashes).
48:The PUT type request is for which type of situation?
A. getDispatcher
B. getDispatcherName
C. getNamedDispatcher
D. getRequestDispatcher
A49: C and D. There are three ways to get the RequestDispatcher. The first is
through Context with
ServletContext.getRequestDispatcher(java.lang.String). Another
way is with ServletContext.getNamedDispatcher(java.lang.String).
This returns a RequestDispatcher object that acts as a wrapper for the
named servlet (in web.xml, the Web application deployment descriptor). The
final way is with
ServletRequest.getRequestDispatcher(java.lang.String). Notice that
you can use a relative pathname for this method. You must use absolutes
with ServletContext.getRequestDispatcher(java.lang.String).
50:Which of the following two options are ways to invoke the doGet method
(choose two)?
Exam Questions
If a partial URL is given and, for whatever reason, cannot be converted into
a valid URL, this method must throw an IllegalArgumentException.
Practice Exam 3
Exam Questions
A. taglib/tag/tag-class
B. taglib/tag/class
C. taglib/tag/name
D. taglib/tag/class-name
A59: A. The taglib/tag/tag-class tag library descriptor element identifies the
class of a tag handler.
60:Which design pattern decouples presentation and service tiers, and provides
a facade and proxy interface to business services?
A. Value objects
B. Model-view-controller
D. Business delegate
A60: D. The business delegate design pattern decouples presentation and service
tiers, and provides a facade and proxy interface to business services.