Download File - If you wish to be out front... then act as if you were ...

spinabundantInternet and Web Development

Jul 30, 2012 (5 years and 1 month ago)

237 views

JAVA PART
-
1………………………..

Whether you consider yourself to be an experienced Java developer or not, it's a safe bet that
you've heard of Java Applets. Applets are little Java programs that run as part of a Web page.
Since they're sort of
'mini
-
applications', they were dubbed 'applets'. Java Servlets got their name
in a similar way.

Think of Servlets as highly efficient CGI programs written in Java. When a Servlet
-
capable Web
server receives a request for a URL that corresponds to a Java Se
rvlet, the server hands the
request off to the Servlet for processing. The Servlet dynamically produces a response to the
request (typically an HTML Web page) and sends it back to the requesting browser. If you think
of Servlets in this context as 'mini
-
se
rvers', their name makes perfect sense.

In this article, I'll take you through the basics of writing and deploying Java Servlets on your
own Web server. I'll begin with the assumption that you're already equipped with a Servlet
-
capable Web server. While th
ere are many offerings in this arena, the free combination of
Apache

and
Tomcat

is the most readily available. Most experienced Java developers prefer one
of the sli
ck, commercial solutions such as
Caucho Resin
,
IBM WebSphere
, or
Allaire JRun

(see
a
complete list
); and while most of these are free for non
-
commercial use, the standard, "nitty
gritty" methods supported by Tomcat are what we'll work with in this article. If you haven't
already set up Apache and Tomcat, now would be a good time.

See my
JSP Quick
-
Start Guide

for a helpful walkthrough, upon which the assumed configuration in this article is based.

By their very nature as Java programs, Servlets require a significant amoun
t of knowledge to
develop with. At the very least, you'll need to be familiar with the basics of the Java language
before you undertake the task of writing your first Java Servlet. The previous articles in this
series,
Getting Started with Java
,
Java Language Basics

and
Object Oriented Concepts in Java
Part 1

and
Part 2

are definitely required reading if you're just making your start in Java
programming.

If you're relatively comfortable with the features of the Java language presented in those articles, and you've got
Apache and Tomc
at running together on your server, you're ready to go! Let's write a Servlet! A Simple Servlet

When it comes right down to it, a Servlet is just a Java class, and you should already know how
to write a Java class:

public class MyClassName {



// ...
properties and methods ...


}

But not just any class will do. Servlets for use on the Web should be subclasses of the
javax.servlet.http.HttpServlet

class, which is built into every Web server that supports
servlets. Although different servers may impleme
nt this class differently, the properties and
methods supported by it are dictated by the
Java Servlet Specification
. As of this writing, version
2.2 is the latest release of the

spec, though version 2.3 is in the final draft stage. The
documentation that makes up the specification includes a
reference

of all of the classes that
Servlet
-
capable servers mus
t provide.

So creating a Servlet is as simple as creating a subclass of
HttpServlet
:

import java.io.*;


import javax.servlet.*;


import javax.servlet.http.*;


public class MyServlet extends HttpServlet {



// ... properties and methods ...


}

Notice
that we're importing the three packages
java.io
,
javax.servlet

and
javax.servlet.http

in the above.
javax.servlet.http

contains the
HttpServlet

class that
we're extending, while
javax.servlet

contains a number of classes related to working with
Servlets an
d
java.io

contains all the standard Java classes for performing input and output.
Since the vast majority of Servlets make use of classes in those latter two packages, it's best to
just include them right off the bat so we don't forget later.

A Servlet mus
t provide at least one method that is used by the Web server to handle requests.
The name of the method(s) depends on the type of request we want to handle. An HTTP GET
request is the simplest form of page request, and comes about either as a result of the

user typing
a URL or clicking on a link. To let your Servlet handle GET requests, you must provide a
method called
doGet

as follows:


public void doGet(HttpServletRequest req, HttpServletResponse rsp)

















throws ServletException, IOException
{





// ... handle GET requests



}

As you can see,
doGet

must be a
public

method that returns nothing (
void
), and takes two
parameters:



An
HttpServletRequest

object (this class is part of the
javax.servlet.http

package), which in the above example we assign to a variable called
req
.



An
HttpServletResponse

object (also in
javax.servlet.http
), which we assign to
rsp
.

When this method is called, the
HttpServletRequest

(
req
) passed as a parameter will be an
object t
hat provides access to all the information related to the browser request that triggered this
Servlet. Using various methods of
HttpServletRequest
, you can find out things like the IP
address of the requesting browser, or the values sent in the URL query s
tring (e.g.
index.html?name=value
). Meanwhile the
HttpServletResponse

(
rsp
) represents the response
to be sent to the browser. It is this object that allows us to send HTML code back to the browser,
for instance. But more on
req

and
rsp

in a moment.

If you
're worried about the
throws ServletException, IOException

portion of the function
declaration, don't be. We haven't covered this in any of the previous articles in this series, but it's
really pretty simple. All this does is indicate the types of
Exceptio
ns

(errors) that may occur as a
result of calling this method. In this case, when the Web server calls the
doGet

function in order
to process a GET request, it must be prepared for the fact that a
ServletException

or an
IOException

may occur, and it must h
andle these errors gracefully. While this sounds scary, it
actually makes our job easier. An
IOException
, for example, could occur if the Web browser
was closed before it finished downloading the response our Servlet was sending it. But since the
doGet

fun
ction is declared such that it may throw (cause)
IOException
s, we don't have to worry
about these errors, since the Web server will handle them for us when they do occur!

Now, in this example, we'll make our Servlet send a simple HTML page to the browser i
n
response to its request. Here's the complete code for the
doGet

method:


public void doGet(HttpServletRequest req, HttpServletResponse rsp)

















throws ServletException, IOException {





rsp.setContentType("text/html");





PrintWriter out

= rsp.getWriter();





out.println("<html>");





out.println("<head><title> Simple Servlet </title></head>");





out.println("<body>");





out.println("<p>This is a simple Servlet!</p>");





out.println("</body></html>");



}

This again isn't as

complicated as it may seem at first glance. Let's step through the body of this
method one line at a time:




rsp.setContentType("text/html");

On this line, we are calling the
setContentType

method of the
rsp

variable (which you'll recall
contains an
HttpServletResponse

object). This method sets the HTTP
Content
-
Type

header to
the
"text/html"

MIME type, which tells the Web browser to expect an HTML Web page. Any
Servlet that generates a Web page must start by setting this content type. Likewise, a Serv
let that
generates a plain text file would set the
Content
-
Type

to
"text/plain"
, and a Servlet that
generated a GIF file would use
"image/gif"
.




PrintWriter out = rsp.getWriter();

Now, since we're going to generate a Web page, we'll want to send HTML code to the Web
browser. HTML code is simply plain text, and the standard Java I/O class for outputting plain
text data is
java.io.PrintWriter
. On this line, we declare a variable calle
d
out

to store a
PrintWriter

(recall that we imported the
java.io

package, so we can refer to this class directly
without giving its fully qualified name). To obtain a
PrintWriter

object that is set up to output
text as the response to the Web browser, we
simply call the
getWriter

method of
rsp
, which
contains our response object, and assign the returned value to our new
out

variable.




out.println("<html>");

The rest of the
doGet

method simply uses the
PrintWriter

(
out
) to output HTML code to the
browser.

Just as in the sample programs in previous articles, where we could output text to the
screen with
System.out.println

(
System.out

is also a
PrintWriter
), we can output lines of
text to the Web browser with the
println

method of our
out

object. Recall that

println

automatically starts a new line at the end of the
String

that it is told to output. If you don't want
to start a new line in the HTML code, you can use the
print

method instead of
println
.

Download the full
MyServlet.java

file or type it out from the listings above and save it
somewhere convenient on your computer (I use a directory called
D:
\
JavaDev
, for example).
Next, we'll see how to compile and deploy a Servlet.

Compiling a Servlet

All of the Java programs we've seen so far were very simple to compile. Unfortunately, if you try
to compile the
MyServlet.java

file we produced in the previous section, you'll get a number of
pretty ugly error messages:

D:
\
javadev> jav
ac MyServlet.java



MyServlet.java:2: package javax.servlet does not exist



import javax.servlet.*;



^



MyServlet.java:3: package javax.servlet.http does not exist



import javax.servlet.http.*;



^



MyServlet.java:5: cannot resolve symbol



sy
mbol

: class HttpServlet



location: class MyServlet



public class MyServlet extends HttpServlet {

































^



...

Now, the best tactic I find when tackling compilation errors is to look at the errors listed at the
top first,
since those errors could actually be causing some of the other errors that are appearing
lower down. In this case, for example, the four "cannot resolve symbol" errors you're likely to
see are actually a result of the two "package does not exist" errors at

the top. Looking more
closely, you'll notice that the compiler is choking on the two
import

commands that we used to
import the
javax.servlet

and
javax.servlet.http

packages. Since it can't import those
packages, we won't be able to use any of the classes

that reside in them, and it turns out that all
of the "cannot resolve symbol" errors refer to places where we're trying to do so.

So why can't it find those two packages? Well, these two packages aren't actually built into Java
like
java.io

is. Instead, t
hey come with the Servlet
-
capable Web server (e.g. Tomcat). So
before the Java compiler will be able to compile our Servlet, we need to let it know where to find
the classes in these two packages.

The classes required are normally stored in a file called
s
ervlet.jar
. The exact location of this
file will depend on the particular Web server software you use, but in the case of Tomcat you can
find it in the
lib

subdirectory of the main Tomcat installation directory (e.g.
d:
\
Program
Files
\
Apache Group
\
jakarta
-
t
omcat
-
3.2.3
\
lib
\
servlet.jar
). For the Java compiler to
be able to compile Servlets, you need to add this file to your Java
class path
. By default, Java
looks for classes in the current directory (
"."
) only. Thus,
"."

is the default class path. If you
chang
e the class path to include the
servlet.jar

file (
".;d:
\
...
\
lib
\
servlet.jar"

under
Windows,
".:/usr/.../lib/servlet.jar"

in Unix), then the Servlet should compile just fine.

You can specify a class path to use when you run
javac.exe

as follows:

d:
\
javadev>

javac
-
classpath ".;d:
\
Program Files
\
Apache Group
\




jakarta
-
tomcat
-
3.2.3
\
lib
\
servlet.jar" MyServlet.java

Obviously, the path to
servlet.jar

can be quite long and painful to type every time you want to
compile a Servlet. As an alternative, you can set an

environment variable called
CLASSPATH

to
your desired class path. Set this the same way you do the
PATH

environment in the particular
operating system you are using (instructions for adjusting the
PATH

environment variable in
various operating systems are

provided in the install instructions for the JDK if you need them).
To temporarily set the
CLASSPATH

environment variable under Windows, you can use the
SET

command on the MS
-
DOS Command Prompt:

d:
\
javadev> SET CLASSPATH=.;d:
\
Program Files
\
Apache Group
\




jakarta
-
tomcat
-
3.2.3
\
lib
\
servlet.jar



d:
\
javadev> javac MyServlet.java

Deploying a Servlet

In its default configuration, Tomcat expects you to place compiled Servlets in the
webapps
\
ROOT
\
WEB
-
INF
\
classes

subdirectory of the Tomcat installation directory

to deploy
them. Place your compiled
MyServlet.class

file in that directory, then (assuming Tomcat is
running on your local computer) load
http://localhost:8080/servlet/MyServlet
. If you
did everything right, you should see a Web page a lot like this one:

If you have Apache installed to
interface with Tomcat using
mod_jk
, you should also be able to view your Servlet with
http://localhost/servlet/MyServlet

(or
http://localhost:8000/servlet/MyServlet

if you have configured Apache to run on port 8000).

Most o
f the time, that's all you need to do to deploy a Servlet! There are some situations,
however, where you'd like to make your Servlet available from a different address. One common
case is when you assign a package name to a Servlet. For example, consider w
hat would happen
if placed the
MyServlet

class in the package
com.sitepoint.web

by adding the line

package com.sitepoint.web;

to the top of the
MyServlet.java

file. To deploy the
MyServlet.class

file, you would place it
in
webapps
\
ROOT
\
WEB
-
INF
\
classes
\
com
\
sitepoint
\
web

(recall that the locations of
.class

files must reflect their package names), and load it with its fully
-
qualified class name
(
http://localhost:8080/servlet/com.sitepoint.web.MyServlet
). Already this is a fairly
ugly URL, and things can get a

lot messier with log package or class names.

For this reason, you may want to assign an alternate name to your Servlet. This is done with the
web.xml

file in the
WEB
-
INF

directory (e.g.
webapps
\
ROOT
\
WEB
-
INF
\
web.xml
). This is an XML
file that lets you conf
igure the Servlets you have deployed. Since XML files are plain text, you
can simply open it in Notepad to make the required changes. When you first install Tomcat,
web.xml

doesn't contain any configuration information:

<?xml version="1.0" encoding="ISO
-
88
59
-
1"?>




<!DOCTYPE web
-
app







PUBLIC "
-
//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"







"http://java.sun.com/j2ee/dtds/web
-
app_2_2.dtd">




<web
-
app>




</web
-
app>

By adding tags between
<web
-
app>

and
</web
-
app>
, you can add configura
tion information for
your servlets. Here's how to assign the name 'my' to
MyServlet
:

<web
-
app>





<servlet>







<servlet
-
name>









my







</servlet
-
name>







<servlet
-
class>









MyServlet







</servlet
-
class>





</servlet>




</w
eb
-
app>

If you save the above changes, then shutdown and restart Tomcat, you will be able to access your
Servlet as
http://localhost:8080/servlet/my
. This may not seem like a big deal, but when
your Servlet's class name is 25 characters in length and is de
eply nested in a package, you'll
appreciate being able to give it a nice, short name.

Assigning your Servlet a name also lets you use that name to specify additional configuration
parameters for your Servlet. The
<servlet
-
mapping>

tag, for instance, lets you map your
Servlet to any URL or URL pattern on your server:

<web
-
app>





<servlet>







<servlet
-
name>









my







</servlet
-
name>







<servlet
-
class>









MyServlet







</servlet
-
class>





</servlet>





<servlet
-
mapping>







<servlet
-
name>









my







</servlet
-
name>







<url
-
pattern>









/my.html







</url
-
pattern>





</servlet
-
mapping>




</web
-
app>

The above code will let you access you Servlet as
http://localhost:8080/my.html

--

completely hiding the fact that you're using a Servlet at all! You can also specify a
<url
-
pattern>

with a wildcard character such as
/my/*
, which would use your Servlet to display any
URL that started with
"http://localhost:8080/my/"
, or
*.blah
, which

would map all
requests for filenames ending in
.blah

to your Servlet. Since the
HttpServletRequest

object
that your Servlet receives lets your Servlet examine the URL that was requested, you could
conceivably map a single Servlet to
/*

and have it handle
every request on your Website,
sending different responses depending on the URL requested!

If you have Apache set up as your main Web server using
mod_jk

to forward requests for
Servlets and JavaServer Pages (JSPs) to Tomcat, you'll find that
<url
-
pattern>

doesn't work as
expected. This is because, by default, Apache will only forward requests for files ending in
.jsp

or files in the
/servlet

directory to Tomcat for processing. To forward additional URL patterns
to Tomcat, you must use the
JkMount

directive

in your Apache configuration file. Make sure you
do this after the line where you
Include

Tomcat's
mod_jk.conf
-
auto

file (which loads the
module required for
JkMount

to work). For example, to map /my/*.blah (all
.blah

files in the
/my

directory) to Tomcat
, you would add the following:

JkMount /my/*.blah ajp13

Note that we specify the more efficient
ajp13

protocol for communication between Apache and
Tomcat for this mapping (Tomcat's
mod_jk.conf
-
auto

file currently uses the older, less
efficient
ajp12

for i
ts default mappings). With that change made, restart Tomcat and Apache and
your mapping should now work through your Apache server.

As you can see, all this deployment and configuration of Servlets is a fairly messy business when
done by standard methods.
Commercial Web servers like those I mentioned in the introduction
often provide nice, graphical administration interfaces that make all these low
-
level
modifications for you in the background. The format of the
web.xml

file, however, is defined in
the Serv
let standard, and is supported by all Servlet
-
enabled servers, even if easier methods are
provided for managing the settings it contains.

A Dynamic Example

The simple Servlet (
MyServlet
) that we have worked with so far isn't terribly exciting, because
it d
isplays the same thing every time it is loaded. The power of Servlets is that they can generate
a new dynamic response every time they are loaded. Common uses of Servlets include retrieving
dynamic content from a database, displaying XML documents as HTML
using XSL stylesheets,
and processing form submissions and taking appropriate actions (e.g. ecommerce applications).

For our first dynamic Servlet, we'll display the current server date and time. Here's the code for
the servlet (
Time.java
):

import java.io.*;





import javax.servlet.*;





import javax.servlet.http.*;





import java.util.Date;










public class Time extends HttpServlet {






public v
oid doGet(HttpServletRequest req, HttpServletResponse rsp)




















throws ServletException, IOException {








rsp.setContentType("text/html");








PrintWriter out = rsp.getWriter();













Date now = new Date(); // The current dat
e/time













out.println("<html>");








out.println("<head><title> Time Check </title></head>");








out.println("<body>");








out.println("<p>The time is: " + now + "</p>");








out.println("</body></html>");






}





}

All in
all, this Servlet is very similar to
MyServlet
. Let's look at what's new:

import java.util.Date;

We import Java's built
-
in
Date

class from the
java.util

package. You can read up on this class
in the Java API documentation if you're curious about its proper
ties and methods.




Date now = new Date(); // The current date/time

We create a new variable called
now

and store a new
Date

object in it. When a Date object is
created, it contains the date and time at which it was created, and will display them when it
is
printed out as part of a
String
:




out.println("<p>The time is: " + now + "</p>");

Compile this file (or download
Time.class
) and deploy it as shown in the previous section. Now,

when you load
http://localhost:8080/servlet/Time

you'll see a page like this one: