[ Team LiB ] Previous Section Next Section

Packaging, Deploying, and Running a Servlet

Although using the invoker is great for experimentation, you should really use a proper technique for deploying and running a servlet. You should package your servlets into WAR (Web Archive) files. A WAR file is similar to a JAR file, but it is specific to Web applications. You can mix servlets, JSPs, HTML files, and even other classes and JAR files within a WAR file. A deployment descriptor named web.xml contains all the necessary definitions for the application, including the list of servlets and their pathnames. Appendix B, "Packaging a Web Application," contains a detailed description of WAR files and their structure. For now, you need to know just a few things to include in the deployment descriptor and how to package your servlets in a WAR file.

Creating a Deployment Descriptor

A deployment descriptor describes a Web application, which may consist of servlets, JSPs, Java classes and JARs, HTML files, and other resources. For the moment, you only need to include servlets in the file. In later hours, you'll see how to add additional items. Listing 2.2 shows a deployment descriptor for HelloWorldServlet.

Listing 2.2 Source Code for web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    version="2.4">
    <display-name>Hello World</display-name>
    <description>A Hello World Web Application</description>

    <servlet>
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>examples.HelloWorldServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

The <?xml?> tag in web.xml defines the file as an XML file. All XML files should contain this tag. For Java Servlet specification version 2.4, deployment descriptors are defined in terms of an XML schema document. Earlier versions were based on DTDs. Servlet containers are required to be backward compatible to version 2.2.

The <web-app> tag defines the main element for this file; it says that this XML file describes a Web application. The next two tags, <display-name> and <description>, provide brief descriptions of the application. The <display-name> tag defines a short name for the application that may be displayed by the servlet container's management interface, or possibly in log files. The <description> tag provides a longer text description of the application.

A web.xml file can contain any number of servlet definitions, each specified by a <servlet> tag that must contain at least a servlet name and a classname. In Listing 2.2, you see a single servlet definition giving the servlet a name of HelloWorld and specifying the classname as examples.HelloWorldServlet.

Defining the servlet is not enough, however, you must also specify a servlet mapping, which maps a URL to a servlet. The <servlet-mapping> tag requires a <servlet-name> and a <url-pattern>. The <servlet-name> element identifies the name of a previously declared servlet. The <url-pattern> element defines the pattern that is used to determine which servlet should be invoked.

To properly understand how to create a url-pattern, it's helpful to look at the parts of the URL that the servlet container receives from the Web server. The following equation is helpful:


requestURI = contextPath + servletPath + pathInfo

When you issue a request to a Web server to invoke a servlet, you include the protocol for the request, the name or IP address of the machine you're directing the request to, and possibly a TCP/IP port if the Web server isn't running on the well-known port 80 for HTTP. The rest of the URL is an identifier used by the container to locate the servlet; it's the part that's the requestURI in the previous equation.

URI Versus URL

graphics/bytheway_icon.gif

You might be wondering what the difference between a URI (Uniform Resource Identifier) and a URL (Uniform Resource Locator) is. Simply put, a URI identifies some kind of an object or resource by name. A URL includes specific information about how to access the resource, such as a scheme (http or ftp) or location. Because a name can include locator information, a URL is a kind of URI. http://www.ietf.org/rfc/rfc2396.txt defines both in detail.


Every application has a context. You'll learn more about contexts in later hours, but they're basically a way to distinguish one application and its resources from another. The contextPath part of the requestURI identifies the context for the application. The contextPath is also sometimes called the application prefix.

The servletPath is the part that we're mostly concerned about when we are defining a url-pattern. It's this part that the url-pattern tries to match. If the url-pattern successfully matches something here, the container has identified the servlet it's going to invoke. The syntax for url-pattern defines these mappings:

  • A string beginning with "/" and ending with "/*" is used for path-mapping. The container will examine the portion of the URI following the contextPath and attempt to make the longest possible match to determine which servlet is invoked. The part of the URI that follows the matched portion is the pathInfo. A servlet can use this for its own purposes.

  • A string beginning with "*." is an extension mapping.

  • A string containing only a "/" character maps to an application's default servlet.

  • Any other string requires an exact match.

Let's look at a few brief examples. We'll use Listing 2.2 as a basis for each mapping. Just picture the URL-mapping element changing while the rest remains the same.

If we used a url-pattern of "/myservlet/*" we could invoke our servlet with any URL whose servletPath started with "/myservlet/". These include

http://localhost:8080/myservlet/

http://localhost:8080/myservlet/onemorelevel/

If we then changed to an extension mapping by using the url-pattern "*.bar", we could invoke our servlet with

http://localhost:8080/foo.bar

Changing the url-pattern to "/" makes our servlet the default servlet, which means that it will be invoked whenever a match for a URL cannot be found.

Finally, looking at the example as-is, we see that the url-pattern is "/hello", meaning that the URL for HelloWorldServlet will have to end with "/hello".

url-pattern, servletPath, and pathInfo

graphics/bytheway_icon.gif

In actuality, the url-pattern is what defines servletPath and pathInfo. The portion of the URI that matches the url-pattern becomes the servletPath. Anything that's left over becomes the pathInfo. However, when designing a url-pattern, it's easier to think of it the other way around, as we have in the text.


Creating the WAR File

You have created the web.xml file, and you are ready to package the Web application into a WAR file. The structure of the WAR files looks like this:


WEB-INF/
WEB-INF/web.xml
WEB-INF/classes/
WEB-INF/lib/

JSP, HTML, and Other Files and Directories

The WEB-INF directory contains the deployment descriptor and directories containing any class files (WEB-INF/classes) or JAR files (WEB-INF/lib). If you have any additional JSP, HTML, or other files, you can add them to the WAR file as well, outside of the WEB-INF directory. Under Windows, you can use the following statements to create a helloworld.war file for the HelloWorld application:


mkdir WEB-INF
copy web.xml WEB-INF
mkdir WEB-INF\classes
javac -d WEB-INF\classes HelloWorldServlet.java
jar cvf helloworld.war WEB-INF

Under Unix or Linux, the procedure is similar:


mkdir WEB-INF
cp web.xml WEB-INF
mkdir WEB-INF/classes
javac -d WEB-INF/classes HelloWorldServlet.java
jar cvf helloworld.war WEB-INF

Be Careful with Case

graphics/watchout_icon.gif

Depending on the platform, the case of directory names is significant. To be certain that your application works, make sure that WEB-INF/ is capitalized.


Deploying the WAR File

Different servlet containers use different procedures to install WAR files. If you are using Tomcat, you can simply copy the WAR file to the webapps directory under Tomcat's main directory and then restart Tomcat. When Tomcat starts, it looks for any WAR files in the webapps directory and then automatically unpacks them and makes the applications available for use. Tomcat won't install a WAR file that is already unpacked, so if you redeploy a WAR file, you must delete the old unpacked directory and restart Tomcat.

When you deploy a WAR file, you must specify the application context somehow. Tomcat uses the name of the WAR file as the name of the application context. For example, if you copy a WAR file named helloworld.war to the webapps directory, the application context is /helloworld/. If Tomcat is running on port 8080 on your local machine, then the full URL for the HelloWorld servlet is http://localhost:8080/helloworld/hello.

Although this packaging process seems a little cumbersome, you will see its usefulness in later hours. You can add additional information to the web.xml file that makes it easier to configure and manage your application.

To make the deployment process easier, you can use Apache's Ant configuration tool (http://jakarta.apache.org/ant) to automatically package a WAR file (you still need to create web.xml manually) and even deploy it to some servlet containers, including Tomcat. Or you can use the Web application manager provided with Tomcat to deploy and manage your applications. You can bring the manager up in a Web browser by using the address http://localhost:8080/manager/html—it is simple to use and is least error-prone.

Using Tomcat Manager

graphics/bytheway_icon.gif

Tomcat's manager application isn't enabled with a default user and password. To use it (and the Administration tool), you'll have to add users with the appropriate rights to tomcat-users.xml in the conf/ subdirectory of your Tomcat installation. See Appendix A, "Apache Tomcat," for instructions.


    [ Team LiB ] Previous Section Next Section