|[ Team LiB ]|
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.
<?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
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:
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
If we then changed to an extension mapping by using the url-pattern "*.bar", we could invoke our servlet with
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
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
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
|[ Team LiB ]|