Server-Side Java with Jakarta-Tomcat
Now that we have installed the JDK, we can install Jakarta-Tomcat. Jakarta is the overall name for Java-related projects sponsored by the Apache Software Foundation, and Tomcat is the ASF's project for servlets and JSPs. (JSPs, as we will see next month, are simply an easy way to create servlets.) Tomcat is meant to be the reference standard for servlets and JSPs on a variety of platforms, making it portable and easy to use Java in server-side web applications.
Unlike a CGI program, which executes within its own UNIX process, and unlike a mod_perl handler, which executes as a subroutine within Apache, servlets execute within a Java virtual machine. This JVM is known as a “servlet container” and can be the server itself (if the server is written in Java), embedded inside of the server or external to the server.
This article assumes that you will be using Apache, in which case the servlet container is external to the HTTP server. However, Tomcat is itself a full-fledged HTTP server, meaning that we can conduct some initial tests without having to configure Apache at all.
You can download and install the latest version of Tomcat from the Jakarta web site at http://jakarta.apache.org/. The Jakarta Project distributes software for a variety of platforms and on a number of schedules, in both source and binary formats. It may take a bit of looking, but you should be able to find a downloadable binary of the latest stable Tomcat release for Linux. As of this writing, the most recent stable version of Tomcat is 3.2.1, which I downloaded in the file jakarta-tomcat-3.2.1.tar.gz.
Once downloaded onto your computer, change to the directory where you want to install Tomcat, and open it up:
cd /usr/java tar -zxvf jakarta-tomcat-3.2.1.tar.gz
Your /usr/java directory will now contain two subdirectories, one named jdk1.3 and the other jakarta-tomcat-3.2.1.
Just as you had to set JAVA_HOME to indicate where your Java distribution is located, you must also set the TOMCAT_HOME variable to indicate where Tomcat was installed. Those using bash can add the following line to one of their startup files:
If you are planning to write your own servlets, you will also need to tell Java where to look for the servlet-related classes. These are located in a Java archive (.jar) file, $TOMCAT_HOME/lib/servlet.jar. If you use bash and don't otherwise set your CLASSPATH, you can set it as follows:
export CLASSPATH=$TOMCAT_HOME/lib/servlet.jar:.You don't need to modify CLASSPATH in this way if you are only planning to run servlets that other people have written. The runtime Java servlet engine knows where to look for the appropriate .jar files, and its CLASSPATH is set correctly when you install Tomcat.
Once you have performed all of these steps, Tomcat is ready to go. You can start it up using the shell script under $TOMCAT_HOME/bin:
A number of diagnostic messages will appear on the screen. However, the main servlet.log log file is normally in $TOMCAT_HOME/logs.
You can check to see if Tomcat works by pointing your browser at port 8080 (the default) on the computer where it has been started. In other words, http://localhost:8080/ should give you a welcome message, indicating that “this is the Tomcat default home page” with some additional links to examples of servlets and JSPs installed on the system. The example servlets should execute correctly, providing you with a demonstration of some simple tasks that we can perform with Tomcat.
Servlet classes are normally installed under a directory named WEB-INF, underneath the directory named in the URL; that is, the example servlet RequestInfoExample, which comes with Tomcat, is available at http://localhost:8080/examples/servlet/RequestInfoExample.
The actual Java .class file (as well as the .java source file for that class) is stored in $TOMCAT_HOME/webapps/examples/WEB-INF/classes/RequestInfoExample.class.
We will soon see how to configure additional directories for servlets. However, we will always have to install our classes under the directory WEB-INF/classes, and the WEB-INF hierarchy will be hidden from public view.
We can test our Tomcat installation by placing a simple servlet, HelloWorld.java (see Listing 2), inside of the directory mentioned above, $TOMCAT_HOME/webapps/examples/WEB-INF/classes/.
Remember that Java requires filenames to match the class names. If you want to change the filename to ABC.java, you will have to change the class declaration inside of the source code to the same name. Otherwise, the Java compiler will complain with a fatal error.
To compile HelloWorld.java into an executable servlet, use the Java compiler, just as we would normally do:
If your CLASSPATH environment variable was not set correctly, javac will complain that it cannot resolve the symbols HttpServletResponse, ServletException and a number of other classes. Rectify this by setting your CLASSPATH to include servlet.jar, as indicated above.
Once the servlet has been complied, you should be able to invoke it with http://localhost:8080/examples/servlet/RequestInfoExample.
If you attach a firstname parameter to the URL, the servlet should print your first name as well: http://localhost:8080/examples/servlet/RequestInfoExample?firstname=Reuven.
As you can see, this servlet is extremely simple. It imports a number of other useful Java packages, including the all-important javax.servlet.* and javax.servlet.http.* hierarchies. We then define our servlet as a subclass of HttpServlet. In doing so, we inherit all of the logic of HttpServlet.
Our HelloWorld servlet is particularly simple and includes a single method, doGet. doGet is invoked whenever the servlet is invoked with the GET method. HTTP supports a number of methods, but the most common are GET and POST; GET is typically used when a user directly requests a URL or clicks on a hyperlink, while POST is used when someone clicks on a “submit” button at the bottom of an HTML form. Because our servlet defines a doGet method but no doPost method, it can only handle GET requests.
The two arguments to doGet describe the HTTP request and response. If we want to retrieve information from the HTTP request, we use a method on our request object. For example, we can retrieve the value associated with the firstname parameter with the getParameter method:
String firstname = request.getParameter("firstname");
If no firstname parameter was passed in the request, the variable, “firstname”, will be assigned the null value. (This is distinct from the empty string, which indicates that the parameter was passed in the HTTP request but contained no value.)
We can similarly affect the HTTP response by invoking methods on our response object. For example, we can set the MIME type of the HTTP response with the setContentType method:
To send information to the user's browser, we use response.getWriter( ), which returns a PrintWriter:
PrintWriter out = response.getWriter();Assuming that we are sending content of type text/html, we can now use out.println to send HTML to the user's browser:
out.println("<HTML>"); out.println("<Head><Title>Hello, world</Title></Head>");