Web Server Programming

Chapter 7
Java Servlets

Caveat

The javax.servlet classes, and the Tomcat servlet engine, are both evolving. This evolution process adds functionality, but sometimes breaks existing code. Methods that were once standard become deprecated in newer versions of the classes. Changes in the Tomcat engine prevent older code from running.

You will encounter problems if you use the latest versions of these systems. For the most part, the problems are easily resolved - providing you can determine what is wrong. Of course, all that you will see is code downloaded from tutorial sites failing to run on your system. If you cannot work out what is wrong, try one of the Java newsgroups (comp.lang.java.*), or go to the servlet focus group in Sun's Java developers site (Sun's developer site may require you to establish a login identity - it is free).

As an example, the switch from Tomcat 3 to Tomcat 4 results in the following problems:

If you try Tomcat 5, you will have to determine the latest changes and corresponding fixes.



Getting Tomcat, javax.servlet.*, and the documentation

Tomcat lives in a subdirectory of the Apache Jakarta site. As usual for major sites, the download location is mirrored; it picks what it thinks is a sensible mirror site for you but you can override the selection. Pick a release build of the current Tomcat (number 4.1.?? - currently available 4.1.18 and 4.1.24) as a Windows .exe file or a Linux/Unix tar.gz file. Note that there are two versions of each; e.g. tomcat-4.1.24-LE-jdk14.exe and tomcat-4.1.24.exe. The one you choose depends on the JDK that you have installed. A current JDK 1.4 includes packages for tasks like XML parsing among its javax extensions. Earlier JDKs didn't have these packages so the code must be included in the Tomcat download. If you have the latest JDK, then you can get the slightly smaller "LE" version of your download.

The Tomcat site has instructions on how to install your new Tomcat.

The download includes HTML documentation, example servlets and JSPs. The library files include the javax.servlet classes that you will need when defining servlet subclasses.


A first servlet

Tomcat is becoming steadily more sophisticated in terms of its features for servlet deployment and management. The download now includes utilities (implemented as servlet/JSP programs) for management of installed web applications. There are also ant scripts that help when compiling you source and deploying applications. These utilities are helpful if you are working seriously on servlet and JSP development. If you are taking an introductory course in which you only going to implement a couple of web applications, then you may find that the time spent learning to use ant etc is not repaid in terms of productivity gain in deploying your one servlet and one JSP. The following instructions ignore the use of ant. Use of the "manager" utility is optional with the Tomcat that you install from the Unix/Linux tar.gz download; the self installing Windows archive configures the installed Tomcat with the manager features enabled.

The following brief outlines give quick guides to setting up a simple servlet (the square root servlet) on a Unix/Linux machine and on a Windows system using the Manager utility. If you get stuck (or if you get a more recent version of Tomcat where the procedures have again changed) then READ THE DOCUMENTATION that comes with the Tomcat that your downloaded.

The first example is the "square root servlet" - simple form, simple processing code. This is deployed as a "web application" consisting of a HTML page, a deployment definition file (web.xml) and a servlet.

Servlet structure

(Windows users note that case matters in file and directory names; it is WEB-INF and web.xml, not variants like Web.xml.)


Basic set up (Unix/Linux)

Download the "tar.gz" file, e.g. jakarta-tomcat-4.1.18-LE-jdk14.tar.gz, from the Apache site. Then:

  1. "Let the cat out"
    gunzip jakarta-tomcat-4.1.18-LE-jdk14.tar.gz
    gtar -xf jakarta-tomcat-4.1.18-LE-jdk14.tar
    
    (It seems that you have to use "gtar" rather than tar.)
  2. Rename its directory (this step is not necessary if you like typing long names).
    mv jakarta-tomcat-4.1.18-LE-jdk14 tom
    
  3. Change to your tom directory and create a little executable file with contents something like the following:
    TOMCAT_HOME=`pwd`; export TOMCAT_HOME
    # Define JAVA_HOME to be the location where your Java system is installed
    JAVA_HOME=/packages/java/jdk/1.4.1; export JAVA_HOME
    ./bin/startup.sh
    echo "REMEMBER TO PUT OUT YOUR TOMCAT BEFORE YOU GO TO BED"
    
    Save as "waketom" and make it executable chmod +x
  4. Now wake your tomcat.
    waketom
    
    (keep this terminal session separate so that you can continue to control your tom)
  5. Start a browser; visit your favorite pages, then go to
    http://localhost:8080
    
    Your Tomcat should respond (don't go directly to your tomcat pages, the Tomcat server is pretty slow starting up!).
    The Tomcat "Welcome" page has numerous links (the majority are to documentation that form part of the download package). These links include:
  6. On first acquaintance, follow the link to the servlet examples supplied by Apache.org.; these are small working examples together with documented highlights of the code.
  7. Back in a terminal window, cd to your tom/webapps directory, and make a demo subdirectory. In demo create a WEB-INF subdirectory. In demo/WEB-INF create a classes subdirectory.
  8. In tom/webapps/demo create a file "formpage.html" with content similar to the following
    <html>
    <head><title>Form Data Entry Page</title></head>
    <body bgcolor=white>
    <hr>
    <h1 align=center >
    Fill in some data
    </h1>
    <p>
    The demo servlet works out square roots, so feed it a number.
    <p>
    <form method=get action="/demo/servlet2">
    <input type=text name=number>
    <input type=submit>
    </form> 
    </body>
    </html>
    
    and chmod it to global read permission
  9. Try to view your page from you web browser:
     
    
    http://localhost:8080/demo/formpage.html
    
    
    Curious, it isn't there.
    Explanation:
    Tomcat looks at its web-apps directory on start up, and only deals out stuff that was there when it started.
    Put your tomcat to rest. (In the window where you started tomcat, do bin/shutdown.sh - actually this won't work if JAVA_HOME is undefined, so fix that as well.)
    Wake a new tomcat (keep this terminal session separate so that you can continue to control your tom)
    Try viewing your page; it should be there this time.
    It is not there? Did you remember to create the WEB-INF subdirectory within tom/webapps/demo? Try: stop your Tomcat, create the WEB-INF and classes directories as noted above; restart your Tomcat. The demo directory should be there now.
    If it isn't -- aaargh. Well it is something to do with the configuration parameters for your tomcat. You can try something like the following:
    http://localhost:8080/manager/install?path=/demo&war=file:/tom/webapps/demo
    
    (Run the manager install task, giving arguments that specify context where webapp is to be deployed and absolute file path to the directory. Now you may have to login in a manager - which means creating an entry for yourself in the tomcat-users.xml file.)
  10. In tom/webapps/demo/WEB-INF create a file web.xml with the content:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    
    <!DOCTYPE web-app
        PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
        "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
    
    <web-app>
    
    	<servlet>
    		<servlet-name>servlet2</servlet-name>
    		<servlet-class>FormServlet</servlet-class>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>servlet2</servlet-name>
    		<url-pattern>/servlet2</url-pattern>
    	</servlet-mapping>
    
    
    </web-app>
    
    This deployment description identifies the servlet class (FormServlet) and associates it with a URL that can be used to invoke it.
  11. In tom/webapps/demo/WEB-INF/classes create a file FormServlet.java with the content:
    import java.io.*;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    
    public class FormServlet extends HttpServlet { 
    
        public void doGet (HttpServletRequest request,
                           HttpServletResponse response)
       throws ServletException, IOException
        {
    	String ending = "</body></html>";
    	response.setContentType("text/html");
            PrintWriter out = response.getWriter();
    	out.println("<html>" +
                        "<head><title> Square roots </title></head>" );
            out.println("<body >" );
    
    	String data = request.getParameter("number");
    	double value = 0;
    	try {
    		value = Double.parseDouble(data);
    	}
    	catch(Exception e) {
    		out.println("<p>Need NUMERIC data.");
    		out.println(ending);
    		return;
    	}
    
    	if(value<0.0) {
    		out.println("You are living in an imaginary world");
    		out.println(ending);
    		return;
    	}
    
    	value = Math.sqrt(value);
    	out.println("Your square root value is " + value);
    	out.println(ending);
    	}
    }
    
  12. Compile your FormServlet.java file.
    There is a small problem. The code references the javax.servlet and javax.servlet.http packages. These aren't included in the standard Java release. You have to modify your classpath so that it includes the necessary files.
    Currently, in Tomcat 4, the files you want are in a jar archive in the common/lib subdirectory of your Tomcat installation. You need to set your CLASSPATH so that the appropriate jar file is included.
    You can compose your own scheme for defining the correct classpath, but the following should work from inside your tom/webapps/demo/WEB-INF/classes directory
    ls ../../../../common/lib
    #Should show a set of jar files including servlet.jar
    echo $CLASSPATH
    #That shows what you usually have in your classpath.
    #This will vary; I have lots of odd classes there associated
    #with Oracle database.
    CLASSPATH=.:../../../../common/lib/servlet.jar:$CLASSPATH
    #That added the servlet stuff (and current working directory) to the libraries that you use
    
    Now you can try
    javac FormServlet.java
    
    It should compile without errors.
  13. Try entering a number in the form that is still in your browser window from step 9.

    The demo servlet works out square roots, so feed it a number.


    It won't work, it says there is no demo/servlet2.
    Remember, Tomcat works with the stuff that was there when it woke up. Your servlet wasn't there then.
    Put down the tom.
    Reincarnate it.
  14. Now try asking for a square root of a number, you should get a meaningful response.

You can of course use the Manager and Administrator tools that are described in the next subsection. All that you need do is create an entry in your tom/conf/tomcat-users.xml file. This entry should define a name and password for a user with roles=admin,manager. The Tomcat home page has links to the login pages for administrator and manager functions. (One of the examples associated with the text requires addition of users to tomcat-users.xml; the file entries are illustrated there).


Windows installation and Using the "Manager" utility

The download for Windows is as an .exe, e.g. tomcat-4.1.24-LE-jdk14.exe; this is a self installing program, simply double click on the icon. Your Tomcat will be installed in C:\Program Files\Apache Group\Tomcat 4.1\ (this will change, check the current documentation); this is the directory where your webapps and conf directories are located. During installation, you will be prompted for a name and password for a user who is to have "admin" and "manager" privileges.

Caution.The installation will create an Apache Tomcat entry in your Start/Programs Windows pop-up menu with options including Start Tomcat and Stop Tomcat. However, by default it installs Tomcat as a Windows service. Services are started automatically when you start your Windows system, so Tomcat is always running (the Start/Stop options in the pop-up menu are ineffective). There are a couple of problems with services. First, you are running a web server at port 8080 whenever you are connected to the Internet (this can violate contracts with some ISPs). Secondly, your web server will be picked up and identified by port scanners. If there are any hacks for attacking a Tomcat server, then your system becomes vulnerable. It is probably wise to use you Windows Control Panel to change your Tomcat from automatic to manual mode.

The 4.18 and 4.24 Windows versions are both configured so that you must utilize "Manager" (simply creating a directory in webapps is not sufficient). The Manager control page allows you to:

(A war "web application archive file" is simply a jar file, created with the jar utility program; the "war" extension simply flags it as a web application.)

A webapplication "installed" into your Tomcat is temporary. It doesn't get copied into your Tomcat's webapps directory and will be gone the next time you restart Tomcat. An uploaded war file is installed into the webapps directory and is therefore more permanent.

For the square root servlet example:

  1. Create a directory where you can create the files for your webapplications, e.g. C:\tmp1\servlets.
  2. Create a subdirectory for the "square root servlet" (C:\tmp1\servlets\demo\) and within this create WEB-INF and WEB-INF\classes subdirectories.
  3. Create the demo\formpage.html, demo\WEB-INF\web.xml, and demo\WEB-INF\classes\FormServlet.java files as shown above.
  4. Use a "Command Prompt" shell window to do the compilation:
    1. Set your PATH variable to include your Java compilers, e.g.:
      set PATH=C:\j2sdk1.4.1\bin\;%PATH%
      
    2. Define a variable with the location of the servlet.jar file, e.g.:
      set SERVLETPATH=C:\Program Files\Apache Group\Tomcat 4.1\common\lib\servlet.jar
      
    3. cd into the directory with you servlet's Java code:
      cd \tmp1\servlets\demo\WEB-INF\classes
      
    4. Define your CLASSPATH, e.g:
      set CLASSPATH=.;%SERVLETPATH%;%CLASSPATH%
      
    5. Compile your servlet:
      javac FormServlet.java
      
  5. Make a war file for you webapplication; still in command prompt:
    cd \tmp1\servlets\demo
    jar -cf demo.war WEB-INF *html
    
  6. Move the war file somewhere else.
  7. Now you can try using Manager to install your webapp.
    Use the "Install form", specify the context as /demo, and the "WAR or Directory URL" as file:C:/tmp1/servlets/demo (note Unix style pathname, not Windows style pathname).
    The application should install and Manager should display an "OK" response.
    Test the application by opening another browser window aimed at http://localhost:8080/demo/formpage.html.
  8. Try using Manager to remove the demo webapplication. Then use the upload form to try to upload the war file created earlier (the upload control lets you browse your file system to find war files.) The webapplication should again be installed, and should again be testable.

Database drivers and other shared code

Servlets may need libraries in addition to the standard Java packages and the servlet extension packages. A web application can include a jar file (archive for a library package) in a lib subdirectory of its WEB-INF directory. Such library jar files are checked when the servlet engine is loading any servlet in your web application.

Typically, all your webapplications will use the same database system. Each could include its own copy of a jar file with the drivers in its WEB-INF; but it is more sensible to place such shared packages in the shared/lib directory of your Tomcat installation.

Windows users with ODBC databases have the Sun jdbc.odbc driver classes available (these are part of the standard Java runtime environment). Use of any other database system requires that you supply the drivers (in the form of a jar archived package). (For example, Oracle drivers are typically distributed as a file classes12.zip; this has to be copied to tom/shared/lib and renamed, e.g. oracle.jar).


System.out.println trace statements

You can include trace statements in the code of your servlets and the code of any helper classes that you use. Output to System.out (also System.err) now goes to a log file in tom/logs; the Windows and Unix/Linux versions differ with respect to the output file used. On Unix/Linux, look for logs/catalina.out. On a Windows system? Depends how you are running it. If you have a manual launch (from the Start Tomcat menu) then there will be a little Tomcat console window and trace outputs probably appear here. Otherwise on a Windows system, look for trace statements in the logs\stdout.log file;


On line resources

When compared to Perl and PHP with their enthusiastic supporters and multiple sites on the web, servlets are lonely and neglected. For servlets, you can go to Sun, and ... er Sun, there are odd articles in Javaworld, and the IBM Developer Works site has some articles (you need to establish a user identifier with IBM, it is free). The OnJava site (part of O'Reilly) has many articles including a few on servlets and JSPs.

There used to be a Servlet Trail in Sun's main introductory tutorial - but Sun's trail keepers have closed that trail and you can no longer go that way. There are two tutorials now that present servlets as part of Enterprise Java and Web Services:

Web services Servlet trail
Enterprise Java Servlet trail

There is another relatively old tutorial still linked to Sun's Java Developer center:

Developer Connection tutorial

Google has a few Servlet links; some are to firms offering to do development for you (their rates are probably too high for students seeking help with assignments). There are also a few sites from where you can download useful servlets and examples; for instance, from the list at Google you can get examples showing how to use servlets for file upload.


Example materials relating to the text

A few of the examples from the text are available.