René Nyffenegger's collection of things on the web
René Nyffenegger on Oracle - Most wanted - Feedback -
 

Creating a Java Web Application

This article tries to show how a simple Web Application is created and deployed to the Tomcat Application Server (running on Windows).
I use the environment variable CATALINA_HOME for the installation location of Tomcat, because I will refer to that location a few times:
C:\>set CATALINA_HOME=\rene\Tomcat_5.0
A Java Web Application has a well defined directory structure. Before I start to create a Web Application, I create this structure for me:
C:\>mkdir \web-app
C:\>cd \web-app
C:\web-app>mkdir src
C:\web-app>mkdir deploy
C:\web-app>mkdir deploy\WEB-INF
C:\web-app>mkdir deploy\WEB-INF\classes
Note, that deploy is the root of the deployed web application. That is, this directory will contain all files that are jarred and deployed to Tomcat. The other directories (currently: src) are not part of this well defined structure.
The src directory will contain the sources for the Web Application.
Usually, a build.xml is needed that goes into the root directory (\web-app). However, for reasons of simplicity, I will leave that out, and compile the project manually with javac and also deploy it with copy.
To keep it simple, I'll use one source file only: WebTest.java
WebTest.java
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public final class WebTest extends HttpServlet {

  public void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws IOException, ServletException 
  {
    response.setContentType("text/html");
    PrintWriter writer = response.getWriter();

    writer.println("<html><head><title>Simple Web Application</title></head>");
    writer.println("<body><h1>A Simple Web Application</h1>");
    writer.println("Here's some text...<br>...and a bit more text");
    writer.println("</body></html>");
  }
}
This file goes, obviously, into the src directory.
It can now be compiled:
C:\web-app>cd src
C:\web-app\src>javac -classpath %CATALINA_HOME%\common\lib\servlet-api.jar WebTest.java
This produces a WebTest.class file:
C:\web-app\src>dir
 Volume in drive C has no label.
 Volume Serial Number is EC22-DD8D

 Directory of C:\wa\src

13.10.2004  08:27    <DIR>          .
13.10.2004  08:27    <DIR>          ..
13.10.2004  08:27               864 WebTest.class
13.10.2004  08:23               772 WebTest.java
               2 File(s)          1'636 bytes
               2 Dir(s)  30'708'645'888 bytes free
servlet-api.jar is the jarfile that contains javax.servlet.ServletException and javax.servlet.http.* which are imported by WebTest.java and must therefore be found in the classpath. If javac doesn't find this jar (or the javax.servlet packages), it will say (or shout, depending on my and javac's mood):
WebTest.java:4: package javax.servlet does not exist
import javax.servlet.ServletException;
                     ^
WebTest.java:5: package javax.servlet.http does not exist
import javax.servlet.http.HttpServlet;
                          ^
WebTest.java:6: package javax.servlet.http does not exist
import javax.servlet.http.HttpServletRequest;
                          ^
WebTest.java:7: package javax.servlet.http does not exist
import javax.servlet.http.HttpServletResponse;
After WebTest.class is created, it can be moved/copied to deploy\WEB-INF\classes:
C:\web-app\src>copy WebTest.class ..\deploy\WEB-INF\classes
        1 file(s) copied.
A web.xml file is needed as well. It basically specifies which URL calls which Java class file. In this case, I want /start-web-test to use WebTest.class:
web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">

<web-app>
  <servlet>
    <servlet-class>WebTest</servlet-class>
    <servlet-name>Some dummy name</servlet-name>
  </servlet>

  <servlet-mapping>
    <servlet-name>Some dummy name</servlet-name>
    <url-pattern>/start-web-test</url-pattern>
  </servlet-mapping>

</web-app>
The web.xml goes directly into deploy/WEB-INF.
Now, the deploy directory is ready to be jarred into a .war file:
cd ..\deploy
C:\web-app\deploy>jar cf MyWebTest.war *
This command has created the desired .war file:
C:\web-app\deploy>dir
 Volume in drive C has no label.
 Volume Serial Number is EC22-DD8D

 Directory of C:\wa\deploy

13.10.2004  08:44    <DIR>          .
13.10.2004  08:44    <DIR>          ..
13.10.2004  08:44             1'591 MyWebTest.war
13.10.2004  08:39    <DIR>          WEB-INF
               1 File(s)          1'591 bytes
               3 Dir(s)  30'708'617'216 bytes free
This .war file must no be copied to Tomcat's webapps directory:
C:\web-apps\deploy>copy MyWebTest.war %CATALINA_HOME%\webapps
Tomcat is now stopped and started:
C:\web-apps\deploy>%CATALINA_HOME%\bin\shutdown
C:\web-apps\deploy>copy MyWebTest.war %CATALINA_HOME%\webapps
C:\web-apps\deploy>%CATALINA_HOME%\bin\startup
Finally, I can now surf to
http://localhost:8080/MyWebTest/start-web-test