Java Servlets

convyancerfollyInternet and Web Development

Nov 13, 2013 (3 years and 9 months ago)

109 views

convyancerfolly_cb7a19ad
-
6d64
-
4d35
-
9354
-
f3a3185b5543.doc



Page
1

of
5

Java Servlets

An introduction to writing and running Java servlets on Linux.

Java servlets are essentially Java programs which extend the functionality of a server. They are not confined to
web servers, but are most often referred to in this context. Virt
ually all references to servlets cite them as a
replacement for CGI scripts, so it is easiest to think of them as Java programs that perform CGI functions.

The intriguing thing about servlets is their claimed performance. Traditional CGI scripts written in

Perl, C, etc.
all have a disadvantage in that a new process must be created for each call of the script. The overhead of process
creation and management can be very taxing on a loaded server. Servlets solve this problem by creating a thread
for each reque
st, rather than an entire process. A single process for each servlet is created, then a request to the
servlet causes a thread to be created to handle it.

Sounds great, but how does one use servlets on Linux? Well, you need a web server that supports both
servlets
and a Java virtual machine. There are several choices in the web server department. Sun's Java Web Server will
probably run on Linux (since it is written in Java), but it is commercial. We'll be using Apache in this article
because it is free and
is widely used. This means we need a servlet extension for Apache. Livesoftware makes a
product called JRun which I have heard great things about, but again, we'll stick strictly to the Apache side of
the world and go with their mod_jserv extension.

Next,
you'll need to choose a JDK (Java Development Kit) for your system. Again, there are several choices.
Two worth mentioning are the Blackdown JDK (
http://java.blackdown.org/

[1]) and the new OpenGroup JDK
(
http://www.camb.opengroup.org/RI/java/linux/

[2]),
which uses a native threads implementation. Since threads
are important to servlet performance, your JDK choice might significantly impact performance. I used the
Blackdown JDK, because I was familiar with it and knew it was stable. However, the OpenGroup'
s work is
worth looking into if you have the time.

To get servlets up and running on your system, follow the steps below. Note I assume the JDK you chose is
installed and working.

The first step is to download the latest version of Apache (
http://www.apach
e.org/

[3]) and the latest version of
JServ (
http://java.apache.org/

[4]). These were 1.3.1 and 0.9.11 respectively, at the time of writing.

The second step is to unpack each of the archives using the
tar

command:

tar
-
zxvf apache_1.3.1.tar.gz

tar
-
zxvf js
erv0.9.11.tar.gz


The third step is to compile Apache with the JServ module. Specify any options you need in the Apache
configuration, but make sure to include an
--
add
-
module

switch to specify where the mod_jserv.c file is located.
Here is a simple exampl
e of an Apache configuration command:


./configure
--
prefix=/usr/local/apache


--
add
-
module=/usr/local/src/


jserv0.9.11/mod_jserv.c


convyancerfolly_cb7a19ad
-
6d64
-
4d35
-
9354
-
f3a3185b5543.doc



Page
2

of
5

This will automatically add the JServ module to your Apache configuration. Once configurati
on is finished, go
ahead and make and install the package:

make

make install


The fourth step is to compile JServ. Before compiling JServ, you must pick a location for installation. If you are
happy with the directory where you unpacked it in step two, th
en you are set. Otherwise, just move the JServ
directory to wherever you want it to reside. To keep things clean, you might want to put it in your Apache
installation tree.

Next, the
CLASSPATH

variable needs to be set. Even though the JServ documentation
suggests this may not be
necessary, I found the package didn't compile unless it was explicitly set. The
CLASSPATH

variable must
specify the path to your JDK classes and the JSDK classes included in the JServ package. My JDK lives in
/usr/local/jdk1.1.6 an
d the JDK classes archive is in the /lib directory of this tree. I have JServ in
/usr/local/apache/jserv, so my
CLASSPATH

variable would be set as follows:

export CLASSPATH=/usr/local/jdk1.1.6/lib/
\

classes.zip:/usr/local/apache/jserv/servclasses.zip

Once
this is set, change to the JServ directory and compile it:

cd /usr/local/apache/jserv

make


Step five is to configure Apache. JServ requires that a number of configuration parameters be added to your
Apache server configuration files. The files are typical
ly located in the /etc directory of your Apache installation
tree. Open up httpd.conf with your favorite editor and add the following configuration directives:

ServletBinary
: the full pathname to your java binary. For example:

ServletBinary /usr/local/jdk
1.1.6/bin/java

ServletClassPath
: specifies the path to your various Java classes. JServ requires you to specify the path to the
JDK, JSDK and JServ classes. For example:

ServletClassPath
\

/usr/local/jdk1.1.6/lib/classes.zip

#path to the JDK classes

Servlet
ClassPath
\

/usr/local/apache/jserv/servclasses.zip

#path to the JSDK classes

ServletClassPath /usr/local/apache/jserv/classes

#path to the JServ classes


ServletAlias
: this is one of the most important directives, since it configures the location of your s
ervlets and
how they are accessed. The syntax of the directive is:

ServletAlias
uri

directory_or_filename


where the
uri

argument specifies how your servlets will be accessed via URLs, and the second argument points
to the actual location of the servlets.

The second argument can either specify a directory containing the servlets
or a ZIP/JAR file containing a collection of servlets.

convyancerfolly_cb7a19ad
-
6d64
-
4d35
-
9354
-
f3a3185b5543.doc



Page
3

of
5

For example, if your ServletAlias directive was

ServletAlias /servlets /usr/local/apache/servlets


then URLs addressing your

servlets would look like http://
yourhostname
/servlets, and the actual servlets would
reside in the /usr/local/apache/servlets directory.

ServletProperties
: gives the location of a file containing properties for your servlets. The path can be absolute or
r
elative to Apache's server root and, if not specified, defaults to

conf/servlets.properties

Many properties can be set within the properties file. Arguments can be passed to all servlets with the
statement:

servlets.default.initArgs=arg1=
val1
,arg2=
val2
,...


Arguments can be passed to individual servlets as follows:

servlet.servletname.initArgs=arg1=
val1
,arg2=
val2
,...


The sixth and final step is to fire up Apache. Well, you should be ready to go at this point, so go into the /sbin
directory of your Apache
tree and start up the server:

cd /usr/local/apache/sbin

./apachectl start


Writing Servlets

The
Servlet

interface provides the foundation for all servlets. All servlets must either implement this interface or
be extensions of a class which implements it.
The Servlet package provides a class called
HttpServlet

which
implements the Servlet interface, so as a servlet developer, much of the work is done for you. The Servlet
interface allows the creation of generic servlets, but we will only look at how to crea
te servlets that act as CGI
scripts. For this, all you have to worry about is the
HttpServlet

class.

Let's step through the code of the simple servlet shown in Listing 1 to see how it works. This servlet overrides
the
doGet

method provided by the
HttpServl
et

class.
doGet

is called when a client makes a GET request to the
servlet. Here we have the servlet respond with a simple web page that gives the standard ``Hello World''
message. The doGet method gets two objects,
HttpServletRequest

and
HttpServletRespon
se
, which encapsulate
information that allows the servlet to obtain information from and communicate with the client. For example,
the
HttpServletResponse

object contains a
PrintWriter

object that can be used to send information back to the
client. In this

example, we use it to send our ``Hello World'' message back to the client. We also use the
setContentType

method of the
HttpServletResponse

object to inform the client that it will be receiving
text/HTML data from the servlet.

Now that we've seen a simple

example, let's step back a bit and look at how HTTP Servlets work. Servlets
extending the
HttpServlet

class handle all of their client requests through its
service

method. The service
method understands standard HTTP requests, and calls appropriate method
s to handle each request. In the
example above, the service would recognize the GET request and call the
doGet

method accordingly. Similarly,
doPost
,
doPut

and
doDelete

methods are provided to handle other types of HTTP requests.

convyancerfolly_cb7a19ad
-
6d64
-
4d35
-
9354
-
f3a3185b5543.doc



Page
4

of
5

The Life Cycle of a Servle
t

A servlet's life begins when the servlet's
init

method is called. The web server calls the init method when it
loads the servlet, but before any client requests are handled. The init method is called only once when the
servlet is loaded. So, if you need
to perform any initialization before your servlet starts handling requests,
overload the
init

method as follows:

public void init(ServletConfig config) throws ServletException {


super.init(config);




...


}


T
he init method is passed an object which contains configuration information about the servlet. It is a good idea
to store this object to make it available if the client needs it. The easiest way to do this is to call the init method
of superclass and pass
the
ServletConfig

object to it. One final tip regarding the initialization of servlets: if your
initialization fails and the servlet can't handle client requests, throw an
UnavailableException
. After
initialization takes place, the servlet is up and the se
rvice method handles client requests.

Finally, when the servlet is unloaded from the web server, its
destroy

method is called. The web server waits
until all service methods are finished or a certain number of seconds have passed (whichever comes first) be
fore
calling the destroy method. In the case of long
-
running service methods, it is possible the destroy method will
be called before all service calls have been completed.

This situation can be handled with a few additional methods and variables. First, c
reate a variable that keeps
track of how many service methods have been called and provide synchronized methods for increasing and
decreasing the counter, as well as one to return the value of your service counter.

public MyServlet extends HttpServlet {



private int numServices = 0;


protected synchronized void enterService() {


numServices++;


}


protected synchronized void exitService() {


numServices
-
;


}


protected synchronized int serviceCount() {


return numServices;


}

}

Now, that

we have these counters, we need to modify the service method to increment and decrement them
accordingly. This is done by adding a call to the
enterService

method at the top of the service method, calling
the service method of the superclass to handle the

real work and then decrementing the counter by calling the
exitService

method.

protected void service(HttpServletRequest req, HttpServletResponse

resp)


throws ServletException, IOException


{


enterService();


try {

convyancerfolly_cb7a19ad
-
6d64
-
4d35
-
9354
-
f3a3185b5543.doc



Page
5

of
5


super.service(req, resp);



} finally {


exitService();


}


}


Next, a flag is needed to determine if the servlet is in the process of shutting down. To accompany this flag, use
accessor methods to set the flag and return its value.

MyServlet continued {


private Boolean e
xiting;


protected setExiting(Boolean flag) {


exiting = flag;


}


protected Boolean isExiting() {


return exiting;


}

}


Now the destroy method should first check if any services haven't completed, then loop until all services are
finishe
d.

public void destroy() {


if (serviceCount() > 0) {


setShuttingDown(true);


}


while(serviceCount() > 0) {


try {


Thread.sleep(interval);


} catch (InterruptedException e) {


}


}

}


Finally, modify any of your methods

that may run for a long time to check if the servlet is shutting down, and
act accordingly.

public void doPost(...) {


/* You could do something like this or put


* the check into a loop


* that takes a long time */


if(!isExiting) {


...


}

}


So there you have it: a quick introduction to getting servlets up and running on your Linux box and writing
some simple ones. If you want to learn more about writing servlets, books are available which cover them in
depth. I would also recommend lookin
g at the Java Tutorial, available on Sun's web site; it contains a nice
introduction to servlets I used when I started learning about them.