www.enhydra.org
 

 
Table of Contents  
       
  A simple WAR example

  A More Interesting web.xml File

  Mapping Servlets to URLs

  Mapping Default and Error Pages

    Defining parameters used by the application

 
    Using the load-on-startup tag

 
    Mapping the slash to a servlet welcome page

 
    The "behind the scenes" web.xml file

 
    Running the Example

 
    Enhydra Issues

 

Introduction to Web Application Archives

by Peter Darrah, Lutris Support Engineer

This FAQ describes how to set up the directory structure of a Web archive or WAR to deploy Java™ servlets, Java Server Pages™ (JSPs), and static content. This description assumes that you have already written some JSPs or servlets and that you are trying to figure out how to run them on the server. Under servlet 2.2, JSPs and servlets are put into a directory structure referred to as a Web application archive or WAR. When the WAR is finished, you can compress it into a file with a .war extension, but setting up the files to compress is the hard part. One advantage to the WAR construct is that once a WAR is set up, it can be moved from server to server without further configuration. A good way to begin understanding how to construct a war is to look at a simple example.

A Simple WAR Example

Assume that you have a JSP called Hello.jsp and a servlet called Hello.java and that you want to deploy them. You could set up the following directory structure:

  • /tmp/webApp
    • myJspDir
      • Hello.jsp
    • WEB-INF
      • classes
        • Hello.class
      • web.xml

The directory structure begins with a document root directory that has an arbitrary name, in this case, webApp. The JSP page can either be in the document root directory or in any of its subdirectories. In this example, it's in an arbitrary subdirectory named myJspDir. The one required subdirectory is called WEB-INF. This special directory contains the configuration file web.xml and a directory called classes that contains the compiled servlet classes. If you are only using JSPs, you do not need a classes subdirectory. The servlet server adds the classes directory to its CLASSPATH, so the server automatically finds servlets you placed in that directory.

The last required file is the web.xml file. It contains deployment information like name mappings, parameters, and default file mappings. The web.xml file in this simple example could contain the following essentially empty file:

               <?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>
               <!-- configuration options would go here -->
               </web-app>
             

Once you register your web application with your servlet runner, you access the above pages with the following URL's:

  • http://your_host/myPrefix/myJspDir/Hello.jsp

  • http://your_host/myPrefix/servlet/Hello

The http://your_host section of the URL gets you to your host. When you configure the servlet runner to run the Web application, you tell it the path to the document root is /tmp/webApp an the URL prefix is some arbitrary string like /myPrefix. Therefore, every request with the prefix myPrefix will be forwarded to the servlet runner which, in turn, looks into your application. The remainder of the URL for the JSP page corresponds to the directory structure. You can put *.html files in the same directory and request them in a similar manner. The call to the servlet requires using the reserved word "servlet" in the url. When the servlet server sees the word "servlet" in the URL, it knows to look for the corresponding class in the classes subdirectory of the WEB-INF directory.

Good Resources

Once you get a simple WAR example working, you will probably want to see a more complicated example. There is an example that goes along with this document. Your servlet server probably also comes with an example WAR. Another good source of information about configuring a WAR is the Servlet 2.2 specification. It's easy to read and includes examples. You can download it from the following URL:

http://java.sun.com/products/servlet/download.html

A More Interesting web.xml File

As mentioned above, the web.xml file describes a number of configuration parameters. The web.xml file in the example above is empty. It contains no configuration parameters. The following web.xml file shows how to do some common configuration tasks. The tasks are describes by comments in bold.

               <?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>
               <!-- The next two sections define name/class mappings. -->
               <servlet>
               <servlet-name>BasicHello</servlet-name>
               <servlet-class>Hello</servlet-class>
               <init-param>
               <param-name>SomeParameter</param-name>
               <param-value>Parameterized hello from the web.xml file.</param-value>
               </init-param>
               </servlet>
               <servlet>
               <servlet-name>PackagedHello</servlet-name>
               <servlet-class>a.b.c.HelloPackage</servlet-class>
               </servlet>
               <!-- The next two sections define name/url mappings. -->
               <servlet-mapping>
               <servlet-name>BasicHello</servlet-name>
               <url-pattern>/Hello</url-pattern>
               </servlet-mapping>
               <servlet-mapping>
               <servlet-name>PackagedHello</servlet-name>
               <url-pattern>/Howdy/*</url-pattern>
               </servlet-mapping>
               <!-- The next two sections define welcome files and the error page. -->
               <welcome-file-list>
               <welcome-file>index.jsp</welcome-file>
               <welcome-file>index.html</welcome-file>
               <welcome-file>myFunkyIndex.htm</welcome-file>
               </welcome-file-list>
               <error-page>
               <error-code>404</error-code>
               <location>/aDirectory/myFavoriteErrorPage.html</location>
               </error-page>
               <!-- This application wide parameter mapping is used to map the / to a page.
               This parameter is used by the index.jsp page in this example. -->
               <context-param>
               <param-name>welcomeServlet</param-name>
               <param-value>/Hello</param-value>
               </context-param>
               </web-app>
             

Mapping Servlets to URLs

The first lines in the web.xml file map servlet classes to arbitrary names. For example, the Hello servlet class is mapped to the name BasicHello. In another example, the mapped class is in a package. The class file for the HelloPackage servlet is located at /someDir/webApps/webApp/WEB-INF/classes/a/b/c/HelloPackage.class. Once the servlet classes are mapped to names, the names can link the classes with arbitrary URL mappings. For example, the HelloPackage servlet is mapped to /Howdy/*, so the following URL brings up the servlet:

http://localhost:8010/myPrefix/Howdy/aBigHello 

Notice there is no use of the reserved word "servlet" in the URL. Frequently, every servlet in a web application is mapped to a corresponding URL to avoid using the word servlet. This example uses the wildcard * (asterisk), but you can map to specific names. The pattern-matching rules are described in more detail in the servlet specification. For security reasons, a single * is the only supported wildcard.

Everything in this section refers to servlets, but JSPs can be mapped to URLs in the same way. Just use the jsp-file tag instead of the servlet-class tag when you define the servlet.

Mapping Default and Error Pages

This section of the web.xml file defines default pages and the error page. The welcome-file-list section lists the default pages. There are three entries there: index.jsp, index.html, and myFunkyIndex.htm. If a URL is called without a page specified, these are the default pages. As an example, assume a WAR has the following configuration:

  • A /tmp/webApp/aDirectory containing a file index.html.

  • The root of the web application is mapped to /tmp/webApp.

  • The URL prefix is mapped to "/myPrefix".

In this case, a call to the following URL would return the contents of index.html:

http://localhost:8010/myPrefix/aDirectory 

If there was another subdirectory webApp/anotherDir with the file myFunkyIndex.htm, a call to the following would return the contents of myFunkyIndex.htm:

http://localhost:8010/myPrefix/anotherDirectory 

The next section defines the default error page. In this case, the 404 File Not Found error is mapped to a page called myFavoriteErrorPage.html in the directory aDirectory. Bogus URLs will map to this page.

Defining parameters used by the application

Virtually every application uses parameters that are set in a configuration file. In the servlet 2.2 model, the parameters used by an application are included in the web.xml file. This example web.xml file includes one parameter set for a servlet and one parameter set for the entire Web application. The Hello servlet includes a parameter defined in the block beginning with the init-param tag. The servlet then gets that value with the following call:

getInitParameter("SomeParameter")
             

The application-wide parameter is defined in the block beginning with the tag context-param. This value can be accessed by any servlet or JSP with the following method call:

getServletContext().getInitParameter( "welcomeServlet" )
             

Servlets talk to each other through the servlet context in a similar manner. For example, if you have a factory class you instantiate on startup and place in the servlet context, then all other servlets can access that factory object through servlet context. A full discussion of JNDI, security, and servlet/EJB communication is beyond the scope of this document, but you should be aware that they are an integral part of servlet 2.2.

Using the load-on-startup tag

While it is not used in this example, the load-on-startup tag is very useful. Virtually all large Web applications start at least one servlet that manages services for the rest of the application. That central servlet might start a database connection pool manager, verify that an email server is working, test a credit card verification service, or instantiate objects used by the rest of the servlets. This tag takes a positive integer as an argument. The number determines what order the servlets are started in. For more information, see the web.xml DTD in the servlet specification. The DTD includes descriptions of other tags not used here, including tags that control the security context and references to Enterprise Java Beans.

Mapping the slash to a servlet welcome page

Mapping the slash to a servlet is an apparently simple problem that requires a somewhat complicated solution. It's a very common task to map the opening page of an application to a servlet. In which case a request to the URL http://foo.com/myPrefix is forwarded to the servlet mapped to http://foo.com/myPrefix/Hello. Note that your application prefix can just be / if you want http://foo.com to go to http://foo.com/Hello.

The most intuitive answer is to simply define a URL mapping to the URL "/". If you take this approach, the mapping appears to act like mapping "/*" and every URL not defined in the web.xml file appears to get the default page. Files like foo.html are no longer served. This behavior comes from the fact that mapping the slash takes over the default servlet. This behavior is defined in the servlet specfication. Because *.html, *.wml, and other static files are handled by the default servlet, the returned request looks like the page you mapped to slash.

One good solution to this problem is to use a JSP page in the document root that forwards the request to your welcome servlet. The server receives the request for the slash and looks for the welcome-file mappings. It finds an index.jsp file and calls it. That JSP file then forwards the request to your welcome servlet. The advantage to this approach is that it leaves the default servlet that comes with the server in place. It also takes advantage of the welcome-file approach defined in the servlet 2.2 specification. An example of this approach is included in the accompanying WAR example. The index.jsp in the example can be copied to any subdirectory and it will forward the request to the default servlet defined in the web.xml file.

An important point to note with this approach is the possible security risk of the default servlet showing directory listings. The Tomcat default servlet will show a directory listing if an URL refers to a directory that does not contain a welcome file. If a directory listing will compromise your site's security, verify that you put an index.jsp or index.html in every directory. For example, assume you have a webApp/media directory containing your site's images. Without a welcome file, a call to http://foo.com/myPrefix/media returns a directory listing of all the images. If you do not want a user to see that listing, put an index.jsp or index.html file in the media subdirectory.

The "behind the scenes" web.xml file

By now you may be wondering if there is some "behind the scenes" web.xml file that defines default mappings. Yes there is. In Tomcat this file is org/apache/tomcat/deployment/web.xml in the JAR file. In Enhydra, this file can be found in the enhydra.jar. You can extract the file from the JAR file using a zip utility or jar itself. Reading this web.xml file is instructive. For example, there is a mapping for "/servlet/*" to the ServletInvoker servlet. If you want to see what the default welcome mappings are, they are listed at the bottom of the file.

Adding MIME types for WAP/WML

While the default web.xml file defines hundreds of MIME mappings, it does not define the MIME mappings used by the WAP protocol. WAP is the protocol used to transmit content to the micro-browsers in cellular telephones. If your WAR contains *.wml and *.wbmp files, you will want to add the wireless MIME types to your web.xml file. The mappings are given in the web.xml file in the demonstration WAR that accompanies this example. With the example running, you can access the following URL from a cellular phone emulator:

 http://localhost:8010/myPrefix/wapPages/Hello.wml

Adding other *.jar files to a Web application

To this point, this FAQ has only described how to add servlets or other classes to the classes subdirectory in the WEB-INF directory. JAR files your application uses are put in the lib subdirectory of the WEB-INF directory. The name lib is a reserved word. From the application server's point of view, it simply adds the WEB-INF/classes directory and every *.jar file in WEB-INF/lib to its CLASSPATH. Servlets do not have to be in the classes subdirectory. They can be anywhere on the application server's CLASSPATH if they are mapped in the web.xml file. Deploying your Web application's servlets in a JAR file in the lib directory is very common.

The images directory

Frequently, a web application has an images or media subdirectory that contains all of the *.gif or *.jpg files. How do you manage this directory during development and deployment? During development you want the images to be part of your WAR, but at deployment time you want the Web server to serve them. Although images and static files can be served from a WAR, the Web server will serve them more efficiently because Web servers are written in native code and are optimized to serve static content.

The following steps describe a possible scenario for serving static content from the WAR during development and the Web server's htdocs directory after deployment.

  1. During development, put your images in an images subdirectory of the top-level Web application directory.

  2. Make links in your HTML relative to "/". For example, the HTML your servlets return contains the following:
    <img src="/images/Enhydra.gif">

  3. During development, use an URL prefix of "/" so all requests go to the Web application.

  4. At deployment time, move all static content from your WAR to the Web server's document directory.

  5. When you configure the Web server and application server, use an URL prefix like myPrefix for your WAR. Images are then served by the Web server, and URLs like /myPrefix/Hello are forwarded to the application server.

Running the example

A WAR example is included with this FAQ. The example is designed to run "out of the box" with Enhydra 3.x. To run the example, follow these steps:

  1. Create a WARConfig directory:


    mkdir /tmp/WARconfig

  2. Download WARconfig.war to /tmp/WARConig.

  3. Change directories to WARConfig:

    cd /tmp/WARconfig

  4. Uncompress the WAR with the following command:

    jar xf WARconfig.war

  5. Edit the top two lines in the Makefile to point to your JDK and Enhydra installation.

  6. Run make.

  7. Change directories multiserver installation make created:

    cd ../multiserver

  8. Start the server:

    ./start

  9. Browse to http://localhost:8010/myPrefix to see the WAR.

This demo runs on the following ports:
8000 MultiserverAdmin
8010 HTTP connection to demo WAR
8020 Enhydra Director connection to demo WAR

Here are interesting URL's you might want to check out:

Enhydra Issues

The previous information applies to any servlet/JSP container that is servlet 2.2-compliant. This section describes issues that are specific to the Enhydra Multiserver servlet runner.

  • You may wonder how to configure a Web application to run under the Enhydra Multiserver. The basic steps are described here:

    1. Run the Multiserver Administration Console.

    2. Choose the Add button and select the WAR radio button.

    3. Fill in the name, Document Root path, and select Servlet Invoker if you intend to use the /servlet/* syntax.

    4. Once the application is added, select the Connections tab. Choose a port and URL prefix.

    5. Start the application by clicking the Start button.

  • Classic presentation object style Enhydra applications are easy to add to a WAR. You can use an Enhydra application, JSPs, and servlets in the same application. Enhydra applications deploy as a single servlet. You can run a classic Enhydra application in any 2.2 servlet server by adding the application's JAR file to the lib directory, entering the Enhdyra Servlet in the web.xml file, and supplying the application's configuration file as an argument. If you are using another application server, be sure to put Enhydra's classes in your CLASSPATH after the server's classes or they will conflict. Here is an example of the web.xml settings:

    <servlet>
    <servlet-name>welcome</servlet-name>
    <servlet-class>org.enhydra.Servlet</servlet-class>
    <init-param>
    <param-name>ConfFile</param-name>
    <param-value>/WelcomeWar/apps/welcome.conf</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>

  • A bug in the 3.x releases prevents you from deploying a WAR in a JAR file. You have to expand the JAR on the file system. There are actually no performance benefits to deploying WAR files because Tomcat just expands WARs files to the file system.

Copyright (C) 1997-2000 Lutris Technologies

Top

Lutris Technologies    Legal Notices    Privacy Policy