Вы находитесь на странице: 1из 11

Story of a Servlet: An Instant Tutorial

Print-friendly Version

By Mark Andrews

You could say that a servlet is what you get when you cross an applet with a CGI script.
From a programmatic point of view, a servlet resembles an applet; it is an executable
that's written in the JavaTM programming language, and it usually (though not always) is
executed in response to an invocation from an HTML page.

From the standpoint of the kind of work it does, a servlet more closely resembles a CGI
(Common Gateway Interface) script. Like a CGI script, a servlet can respond to user
input -- such as the clicking of a button on a form -- and can either collect information
from the user or send information back to the user (or both), depending upon what kinds
of actions are initiated by the form the user fills out. If a servlet is designed to provide
information to the user, it can track down the information it needs in any number of ways
-- by retrieving it from a database, for example. The servlet can then dynamically
construct an HTML page containing the information it has collected, and can display that
page in the user's browser.
"Because they are designed to fulfill the "Write Once, Run AnywhereTM" promise
inherent in the Java programming language, servlets can be executed without
modification on any platform."

Servlets are not the only mechanism that can interact in this way with a user. CGI scripts
can perform similar operations -- and indeed, until servlets came along, CGI scripts were
the standard mechanism for creating and displaying HTML pages dynamically. But
servlets have many advantages over CGI scripts, and are quickly replacing them in the
world of enterprise computing.

One way in which a CGI script is inferior to a servlet that a CGI script spawns a new
process every time it is executed, consuming more and more processing time -- and more
and more server resources -- every time it is invoked. Also, CGI scripts are platform-
dependent and cannot take advantages of many of a server's capabilities because they run
in processes that are separate from the server's process. For example, a CGI program
cannot write to a server's log file.

Servlets do not have any of these liabilities. They are efficient and scalable because they
don't create new processes every time they execute; instead, servlets are handled by
separate threads within the Web server process. They can write to server log files and can
take advantages of other server capabilities because they run in the server's own process.
And, because they are designed to fulfill the "Write Once, Run AnywhereTM" promise
inherent in the Java programming language, servlets can be executed without
modification on any platform.

How Servlets Work

Writing Servlets with IDEs


Before you can invoke a servlet, you must compile it. Many vendors offer IDEs equipped
with servlet wizards that make it easy to create and compile servlets almost automatically.
The Guestbook servlet presented in this article was created and compiled using IBM's
WebSphere Studio IDE. You can download a free trial version of WebSphere Studio from
theIBM Web site.

This article introduces servlets and shows how they can be used in applications written in
accordance with the Sun BluePrints Design Guidelines for the JavaTM 2 Platform,
Enterprise Edition (J2EE). The article presents an example servlet that you can invoke,
study, and -- if you like -- download for more experimentation.

The example servlet is named Guestbook. When you invoke it, the servlet displays a
Guestbook page and prompts you to type in some information about yourself. When you
fill in the requested data and click a Submit button, the servlet checks to see if you have
provided all the data that it feels it needs for a complete database entry. If you have failed
to fill in any critical fields -- not just any fields, but any critical fields -- the servlet
prompts you to supply the missing data.

Finally, when the servlet has collected all the information it has asked for, it adds the data
you have entered to a text file that serves as a database.

To see how the Guestbook servlets works, you must compile it and then install it on a
Web server -- or, if you don't have access to a Web server, on a workstation equipped with
special software for running servlets locally. One such software package is the
servletrunner tool, which you can read about and then download at no cost from the Java
Tutorial.

Whether you decide to compile and invoke the servlet or not, you'll get an opportunity
later in this article take a look at its source file. You can also examine the source file of
the HTML page that invokes the servlet. If you like, you can download both the servlet
and the HTML page that calls it. Then, if you like, you can download and install
servletrunner and play around with Guestbook servlet at your leisure -- and, perhaps, use
it as a stepping stone for creating similar servlets of your own.

Invoking a Servlet
As mentioned earlier, in the first paragraph of this article, a servlet is an executable that's
written in the Java programming language. Servlets are supported through the Servlet
API, an extension to the Java programming language.

To create a servlet, you must write a program that implements the javax.servlet.Servlet
interface. Most servlets implement this interface by extending either the
javax.servlet.GenericServlet class, which is implemented in the javax.servlet package, or
the javax.servlet.http.HttpServlet class, which provides extra functionality needed by
HTTP servlets and is implemented in the javax.servlet.http package. Almost all servlets
written today are designed to use the HTTP protocol, so most servlets currently extend
the javax.servlet.http.HttpServlet class.

One of the most common ways to invoke a servlet from an HTML page is to provide a
link to it from a button on a form. You can also invoke a servlet by embedding a link to it
in an HMTL page, or even by typing its pathname into the Address bar of a browser. Still
another way to invoke a servlet is to call it from another servlet -- but we won't go any
further into that option in this article.

The Java Servlet API provides a number of methods that servlets can (and do) override.
One method you will always override is the init() method. (Servlets, like applets, are
always equipped with an init() method rather than a main() method). Two other methods
that are commonly overridden are the doGet() method, which retrieves data in response to
GET actions embedded in a form, and the doPost() method, which posts data in response
to POST requests.

When a user invokes a servlet by clicking a button or using some other mechanism that
activates a link to the servlet, the Web server that is hosting the user's browser session
tracks down the servlet by looking in a special directory. The name of this directory can
vary, depending on the Web server or application server being used. But no matter what
the actual pathname of the directory is, an HTML page that invokes a servlet can always
use the /servlet alias to find the servlet it's looking for. For instance, the HTML code

<FORM METHOD=GET ACTION="/servlet/HelloWorld">

will always invoke a servlet named HelloWorld -- provided, of course, that (1) the Web
server being used supports servlets and (2) a "Hello World" a servlet actually exists in the
directory in which servlets are stored on your Web server.

Using a Servlet

Figure 1 shows one of the most common ways of using a servlet. A user (1) requests
some information by filling out a form containing a link to a servlet and clicking the
Submit button (2). The server (3) locates the requested servlet (4). The servlet then
gathers the information needed to satisfy the user's request and constructs a Web page (5)
containing the information. That Web page is then displayed on the user's browser (6).

Example: The Guestbook Servlet

We have scarcely begun to cover what there is to know about servlets. But we do have
enough information now to take a look at the Guestbook servlet, the example servlet that
is provided with this chapter.

To access a servlet, you simply invoke it by writing a line of HTML code on an ordinary
HTML page. To take a look at the HTML code that invokes the Guestbook servlete, just
click the red HTML button:

The page that invokes the Guestbook servlet looks pretty busy, but it's really just a plain
old static HTML page, and only a line or two of its HTML code is directly related to the
invocation and execution of a servlet. Here's a line of HTML code that isn't directly
connected with a servlet but sets things up for invoking one:

<INPUT TYPE="submit" NAME="InvokeServlet" VALUE="Submit">

If you've ever worked with forms on the HTML level, you know what this line does: It
creates a button that the user can click to submit a form. Farther down on the page, we
see another line of HTML code that invokes a servlet when the user clicks the Submit
button:

<FORM METHOD="POST" ACTION="/servlet/FormDisplayServlet">

As we have seen, servlets always reside in a directory that can be accessed using the alias
/servlet. So it's easy to see what the preceding line does: It sends some data -- in this case,
all the data that the user has entered on the Guestbook form -- to a servlet named
FormDisplayServlet, which resides in the Web server's /servlet directory.

Other Features of the Guestbook HTML Page

A large chunk of the Guestbook servlet is the part that collects information from the user.
This part of the servlet displays a number of text fields and combo boxes that the user can
fill in. For example, this line of HTML code creates the first text field on the page -- the
field in which the user types his or her first name:
<INPUT TYPE="text" NAME="firstname" VALUE="" SIZE=44 MAXLENGTH=30>

The Guestbook HTML page uses combo boxes to collect other kinds information. This
block of code creates a combo box that is used to request the user's occupation:

<select name="profession">
<option>Select One
<option>Student
<option>Homemaker
<option>Computer-related
<option>Business/Office
<option>Sales
<option>Industry
<option>Education
<option>Sports
<option>Entertainment
<option>Agriculture/Outdoors
<option>Other
</select>

When the user has finished filling in the Guestbook form, she clicks the form's Submit
button. The Guestbook program's HTML page then tracks down and executes the form-
display servlet, which analyzes the user's data and then responds to it. You'll see how that
happens in the next section, "How the Guestbook Servlet Works."

How the Guestbook Servlet Works

Now that you've seen how the Guestbook program's HTML page works, we're ready to
take a look at the Guestbook servlet. At the end of this section, you'll get a chance to
examine the servlet's source file in its entirety. First though, it might be helpful to break
the servlet down into parts and take a look at some of its individual routines.
Maybe We Should Add a Bean . . .

In the Guestbook servlet's source file, the code that implements the servlet is all mixed up
with code that analyzes user input to see whether the user has filled in all critical fields.
That coding technique makes it easy to see exactly what an instructional servlet does,
because all of the servlet's code is in your face at all times. In a real-world servlet,
though, a better technique might be to strip out all the input-analysis code and
encapsulate it in a JavaBean. That modification would streamline the servlet and would
make it possible to update or improve the servlet's supporting data-analysis code later on
without touching the servlet itself. In an upcoming issue, we'll present a follow-up
tutorial that will show how a JavaBean could improve the Guestbook program.
Analyzing Input Data

The Guestbook servlet's source file is named FormDisplayServlet.java. The servlet


instantiates just one class, named FormDisplayServlet.

The FormDisplayServlet.java source file looks rather complicated at first glance, but
most of the logic it that contains is devoted analyzing the user's input to ensure that no
required fields are left blank. That is an important task because the purpose of the
Guestbook form is to collect data, and the data that's collected is not worth much if the
user leaves critical fields blank -- for example, if the user fails to type in his or her first
name or last name, or leaves the city or country fields blank.

The init() Routine

The first method that's called in the Guestbook program is an override of the init()
method defined in the javax.servlet.http package. The first part of the init() method used
in the Guestbook servlet looks like this:

public void init(ServletConfig config)


throws ServletException
{
super.init(config);
connections = 0;
}

boolean error;
String want_offers = "YES";
String want_info = "YES";
Enumeration params;
String[] entries = {"", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", ""};

// This servlet keeps track of a lot of strings.


// These are the names of variables.
public final String[] parms = {"firstname", // 0
"lastname", // 1
"age", // 2
"profession", // 3
"email", // 4
...

// These are the same variables, expressed as


// labels that are written in English and look nicer
// on the page.
public final String[] labels = {"First Name", // 0
"Last Name", // 1
"Age", // 2
"Profession", // 3
"Email", // 4
"Home Page", // 5
...
};

As you can see, the first thing the Guestbook servlet's init() method does is override its
superclass's init() method by calling super.init(config). Currently, that's a required call in
every HTTP servlet. So it's probably best to take care of it right away and then move on
to more interesting routines.

After overriding super.init(), the Guestbook servlet defines a number of variables,


including a couple of arrays to help it keep track of its parameters. Then the program calls
the doPost() method, which does three things:
It analyzes the user's input.
It stores that input in a text file that's used as a makeshift database.
Finally, it sends a response back to the user.

You'll see how all three of those operations work in the remaining sections of this article.

The doPost() Method

When the Guestbook servlet has executed its init() function, it overrides the HttpServlet
class's doPost() method. At first glance, Guestbook's doPost() routine looks quite
complex. Actually, though, the first half of the routine is nothing but a series of
statements that define the variables used for each of the servlet's parameters. These
variable definitions are so cut-and-dried that the code initiating them can actually be
generated automatically. In fact, this part of the Guestbook's source file was automatically
generated, using IBM's WebSphere Studio IDE (see box).

Here's the initial part of the Guestbook servlet's doPost() method:

public void doPost(HttpServletRequest request,


HttpServletResponse response)
throws ServletException, IOException {

// This line tells the servlet where the database is.


String guestbook = request.getRealPath("guestbook.txt");
//First name
String firstname = "";
try
{
firstname = request.getParameter("firstname");
}

catch (Exception e)
{
e.printStackTrace();
}

userName = firstname;

//Last name
String lastname = "";
try
{
lastname = request.getParameter("lastname");
//Age
String age = "Select One";
try { age = request.getParameter("age");
}

catch (Exception e)
{
e.printStackTrace();
}
...

Once all this preparatory work is done, the Guestbook servlet is finally to get down to
business. Here are the lines in which that starts to happen:

response.setContentType("text/html");
PrintWriter pw = new PrintWriter (response.getOutputStream());

pw.println("");
pw.println(" <head><title>GuestBookServlet</title></head>");
pw.println("");
These five lines are worth studying closely. Here's what they do:
The response.setContentType() method -- in the first line of the preceding code fragment
-- informs the servlet object we are creating that the next thing it will see is some data
that should be treated as HTML text.

The second line in the code fragment instantiates an object called a PrintWriter, which is
defined in the Servlet API. A servlet can use a PrintWriter or a number of things, one of
which is to write text to Web pages.

Next come three lines of code that actually do create some text which will shortly be
displayed on a Web page. The first statement creates a data stream that will print a blank
line when it is sent to the user's Web browser. The second line sets up a data stream that
will print a title on the Web page that the servlet generates. The third statement creates a
stream that will print another blank line.

The Rest of the doPost() Method

The rest of the doPost() method is fairly straightforward. First there's a loop that uses a
switch statement to check the thoroughness of the user's input. If the servlet determines
that that one or more required fields have been left blank, it calls a method named
printErrorPage(). The printErrorPage()method displays an HTML page that prompts the
user to go back and fill in the omitted fields. If no errors are detected, doPost() calls a
method named printData(), which adds the user's input to a database (actually just a text
file) and then thanks the user. Here's the code that determines which of those pages
should be displayed, and then sends the selected page back to the user:

// If any required field has been left blank,


// we display an error page.

if (error == true)
{
params = request.getParameterNames();
printErrorPage(pw, params, true);
}

// If no important items have been left blank,


// we display the Thank You HTML page and update the
// database with the user's input.

else
{
// This is the method that prints the data to the database
// and displays the Thank You HTML page.
printData(null, null, dbString, guestbook, pw);
}
...

When the doPost() method has sent an appropriate response page to the user, the servlet
sets up an output stream that will print a </body> tag and an </html> tag to out the Web
page it is creating. Then doPost() concludes its own work with by calling the
PrintWriter.close() method:

...

pw.println("");
pw.close();
}

The printErrorPage() and printData() Methods

The printErrorPage() and printData() functions are the first functions we have examined
that are not overrides of HttpServlet methods. Instead, they are custom routines unique to
the Guestbook servlet. The printErrorPage() method is particularly worth studying
because it shows quite clearly how a servlet can generate a complete HTML page. In this
case, printErrorPage() constructs a Web page containing an error message if it has been
determined that the user has left one or more required fields blank. Then the error page is
sent back to the user and displayed in the user's browser:

public void printErrorPage(PrintWriter pw, Enumeration e,


boolean errorStatus) throws IOException
{
// This loop prints the error message.
pw.print("<H1>Oops!</H1>);

pw.print("<BR>");
pw.print(s8 + "<BR>"); // s8 and s9 are predefined strings;
pw.println(s9 + "<BR><P>"); // see complete source listing.

for (int n = 0; n < NR_OF_PARAMS; n++) {


if (entries[n] == "ERROR") {
pw.println(labels[n]);
pw.print("<BR>");
entries[n] = "";
}

}
pw.println("</BODY></HTML>");
pw.flush();
pw.close();
return;
}

// end of printErrorPage()

The printData() method is a little more complicated; before it dispatches its page to be
printed, it checks to see which required fields on the Guestbook form have been left
blank, and then it tells the user exactly what fields still need to be filled in. Those
operations aren't directly related to the overall creation and implementation of servlets, so
you we won't dwell on them here. But they are commented pretty thoroughly in the
Guestbook servlet's source code, and you can check them out there if you're interested.

To examine the servlet's source code, just click the Servlet button:

Вам также может понравиться