Related Apache Articles on O'Reilly Network's ONLamp.com: Getting, Installing, and Running Apache Securing Your Apache Serve (Chapter 3 from Apache: The Definitive Guide) AxKit: An XML-Delivery Toolkit for Apache An Amble Through Apache Configuration Also in Using Tomcat: Using Tomcat 4 Security Realms |
In this article we are going to cover the deployment of web applications using Tomcat. We are performing a manual deployment to fully explain the steps involved when deploying a web application.
The best way to describe the deployment process is to create a web application
of our own that includes the important components found in most Java web
applications; then package it for deployment. The following sections will
take you through the steps involved in deploying a web application. The name
of our web application will be onjava
.
In this article, we
The first thing you need to do is create the directory structure that will contain the application. We discussed this structure in Part 1, Java Web Applications, and I include the relevant details in Table 1.
Table 1. The Web Application Directory Structure |
|
Directory |
Contains |
/onjava | This is the root directory of the web application. All JSP and XHTML files are stored here. |
/onjava/WEB-INF |
This directory contains all resources related to the application that are not in the document root of the application. This is where your web application deployment descriptor is located. Note that the WEB-INF directory is not part of the public document. No files contained in this directory can be served directly to a client. |
/onjava/WEB-INF/classes | This directory is where servlet and utility classes are located. |
/onjava/WEB-INF/lib | This directory contains Java Archive files that the web application depends upon. For example, this is where you would place a JAR file that contained a JDBC driver. |
The name of our web application, onjava
, is the root
of our directory structure.
While in development I suggest creating the directory directly in
the Tomcat /webapps
directory. When it comes time for
deployment, you can package your web application into a WAR file and
go though the production deployment process.
The last step in creating the web application directory structure
is adding a deployment descriptor. At this point you'll be creating a
default web.xml file that contains only the DTD, describing the
web.xml
file, and an empty web.xml
file.
Listing 1 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>
</web-app>
Now copy this file to the TOMCAT_HOME/onjava/WEB-INF/
directory, and we'll begin adding web application components to it in
the following sections.
|
After you've created the web application directory structure, you
must add a new ServletContext
to Tomcat. The
ServletContext
defines a set of methods that are used by
components of a web application to communicate with the servlet
container. The ServletContext
acts as a container for
the web application. There is only one ServletContext
per web application. We will discuss the relationship between a
ServletContext
and its web application in much more
detail in Part 4, "Web Applications and the ServletContext."
To add a new ServletContext
to Tomcat you need to add
the following entry to the TOMCAT_HOME/conf/server.xml
file, setting the values for the path
and
docBase
to the name of your web application. Notice again
that the name we are using is onjava
.
<Context path="/onjava" docBase="onjava" debug="0" reloadable="true" />
There are two things here we need to focus on. The first,
path="/onjava"
, tells the servlet container that all
requests with /onjava
appended to the server's URL belong to the
onjava
web application. The second,
docBase="onjava"
, tells the servlet container that the
web application exists in the /onjava
directory.
Now that you have created the web application directories and added
ServletContext
, you can add server-side Java
components. The first components we are going to add are JSPs.
The first JSP will include a simple login screen. Listing 2
contains the source for the login.jsp
page.
Listing 2 login.jsp
<html>
<head>
)B <title>OnJava Demo</title>
)B <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" onLoad="document.loginForm.username.focus()">
)B <table width="500" border="0" cellspacing="0" cellpadding="0">
)B <tr>
)B <td> </td>
)B </tr>
)B <tr>
)B <td>
)B <img src="/onjava/images/monitor2.gif"></td>
)B </tr>
)B <tr>
)B <td> </td>
)B </tr>
)B </table>
)B <table width="500" border="0" cellspacing="0" cellpadding="0">
)B <tr>
)B <td>
)B <table width="500" border="0" cellspacing="0" cellpadding="0">
)B <form name="loginForm" method="post" action="servlet/com.onjava.login">
)B <tr>
)B <td width="401"><div align="right">User Name: </div></td>
)B <td width="399"><input type="text" name="username"></td>
)B </tr>
)B <tr>
)B <td width="401"><div align="right">Password: </div></td>
)B <td width="399"><input type="password" name="password"></td>
)B </tr>
)B <tr>
)B <td width="401"> </td>
)B <td width="399"><br><input type="Submit" name="Submit"></td>
)B </tr>
)B </form>
)B </table>
)B </td>
)B </tr>
)B </table>
</body>
</html>
As you look at this JSP, you'll see nothing very special about
it. The only thing you should pay attention to is the
action
of the form. It references a servlet in the
package com.java
named login
. This servlet
will retrieve the username-password parameters from the request and
perform its own processing.
There isn't much to deploying a JSP. You just copy it to the public
directory of your web application, which in this case is
TOMCAT_HOME/webapps/onjava/
. Any images that it
references should be placed in an images folder that you have created
in the /onjava
directory.
To see this JSP in action, open the following URL in a browser:
http://localhost:8080/onjava/login.jsp
|
If you changed the default HTTP port, as mentioned in Installing and Configuring Tomcat, you will need to request the URL from the appropriate port value. If everything was configured correctly, you should see an image similar to Figure 1.
|
If you do not see a page similar to this image, make sure you have the
correct entry in the server.xml
file, as described in the
section, "Creating a Web Application ServletContext."
The second JSP is the target JSP referenced by the servlet defined in the following section. This JSP will retrieve the request attribute USER that was added to the request with the following servlet. It will then output the String value of the attribute. Listing 3 contains the source for the target JSP.
Listing 3 welcome.jsp
<html>
<head>
)B <title>OnJava Demo</title>
)B <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
)B <table width="500" border="0" cellspacing="0" cellpadding="0">
)B <tr>
)B <td> </td>
)B </tr>
)B <tr>
)B <td>
)B <img src="/onjava/images/monitor2.gif"></td>
)B <td>
)B <b>Welcome : <%= request.getAttribute("USER")
%></b>
)B </td>
)B </tr>
)B <tr>
)B <td> </td>
)B </tr>
)B </table>
</body>
</html>
As we stated earlier to deploy this JSP, you simply need to copy it to
the public directory of your web application, which in this case is
TOMCAT_HOME/webapps/onjava/
.
The next component to add is a servlet. This servlet will be the
action of login.jsp
's form. It will retrieve the username
and password values from HttpServletRequest
, look up the
associated user, and then forward the request to a target JSP. The
source code for this servlet can be found in Listing 4.
For our example the value of the USER
is
static. Normally you would perform a real lookup of some sort, but, to
keep things simple, I'm just returning String Bob
.
Listing 4 com.onjava.login.java
package com.onjava;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
public class login extends HttpServlet {
)B private String target = "/welcome.jsp";
)B private String getUser(String username, String password) {
// Just return a static name
)B // If this was reality, we would perform a SQL lookup
)B return "Bob";
)B }
)B public void init(ServletConfig config)
)B throws ServletException {
)B super.init(config);
)B }
)B public void doGet(HttpServletRequest request,
)B HttpServletResponse response)
)B throws ServletException, IOException {
)B // If it is a get request forward to doPost()
)B doPost(request, response);
)B }
)B public void doPost(HttpServletRequest request,
)B HttpServletResponse response)
)B throws ServletException, IOException {
)B // Get the username from the request
)B String username = request.getParameter("username");
)B // Get the password from the request
)B String password = request.getParameter("password");
)B String user = getUser(username, password);
)B // Add the fake user to the request
)B request.setAttribute("USER", user);
)B // Forward the request to the target named
)B ServletContext context = getServletContext();
)B RequestDispatcher dispatcher =
)B context.getRequestDispatcher(target);
)B dispatcher.forward(request, response);
)B }
)B public void destroy() {
)B }
}
To deploy a servlet as part of a web application you first need to
compile the servlet and move it into the web application's
/WEB-INF/classes
directory. For this example, you should
compile this servlet and move it to the
/onjava/WEB-INF/classes/com/onjava/
directory.
This class file is in the subdirectory com.onjava
because of its package name.
|
The next step in deploying the login servlet is to add a servlet
entry into the web application's web.xml
file. An example
<servlet>
element can be found in the following
code snippet.
It isn't necessary to add all servlets to the web.xml
file; it's only necessary when the servlet requires additional
information, such as initialization parameters.
Example <servlet>
Element
<servlet>
)B <servlet-name>ExampleServlet</servlet-name>
)B <servlet-class>packagename.ExampleServlet</servlet-class>
)B <init-param>
)B <param-name>parameter</param-name>
)B <param-value>value</param-value>
)B </init-param>
)B <load-on-startup>1</load-on-startup>
</servlet>
This servlet entry contains a simple servlet definition. A description of each of its parts can be found in Table 2.
Table 2. The Sub-elements of a |
|
Sub-element | Description |
<servlet-name> | The
|
<servlet-class> | The
|
<init-param> | The
|
<load-on-startup> | The
|
To add our login servlet we need to make the following entry into the
TOMCAT_ROOT/onjava/WEB-INF/web.xml
file:
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.onjava.login</servlet-class>
</servlet>
That's all there is to it. To see your web application in action, restart the Tomcat server and open the following URL in your browser:
http://localhost:8080/onjava/login.jsp
You should see an image similar to Figure 1 (which was referred to above). Now enter a username and password and press the "Submit Query" button. If everything went according to plan, you should see an image similar to Figure 2.
|
If you didn't see an image similar to Figure 2, make sure that you
have the servlet class in the appropriate directory and the entry in
the web.xml
file matches the code snippet referenced
above.
The final component that we're adding is a tag library. This
library contains a single tag, HelloTag
, that replaces
every occurrence of the text <onjava:hello/>
with
the literal string "Hello". While this is a perfectly silly example of
a tag library, it allows us to present a practical example of
deploying a tag library. The source code for the tag handler can be
found in Listing 5 and the source for the tld
can be
found in Listing 6.
Listing 5 HelloTag.java
package com.onjava;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
public class HelloTag extends TagSupport
{
)B public void HelloTag() {
)B }
)B // Method called when the closing hello tag is encountered
)B public int doEndTag() throws JspException {
)B try {
)B // We use the pageContext to get a Writer
)B // We then print the text string Hello
)B pageContext.getOut().print("Hello");
)B }
)B catch (Exception e) {
)B throw new JspTagException(e.getMessage());
)B }
)B // We want to return SKIP_BODY because this Tag does not support
)B // a Tag Body
)B return SKIP_BODY;
)B }
)B public void release() {
)B // Call the parent's release to release any resources
)B // used by the parent tag.
)B // This is just good practice for when you start creating
)B // hierarchies of tags.
)B super.release();
)B }
}
Listing 6 taglib.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
)B PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<!-- a tag library descriptor -->
<taglib>
)B <tlibversion>1.0</tlibversion>
)B <jspversion>1.1</jspversion>
)B <shortname>onjava</shortname>
)B <uri>/onjava</uri>
)B <tag>
)B <name>hello</name>
)B <tagclass>com.onjava.HelloTag</tagclass>
)B <bodycontent>empty</bodycontent>
)B <info>Just Says Hello</info>
)B </tag>
</taglib>
To deploy this tag library, we need to make an entry to the
web.xml
file. The modified web.xml
file can
be found in Listing 7.
Listing 7 web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC
)B '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
)B 'http://java.sun.com/j2ee/dtds/web-app_2_3.dtd'>
<web-app>
)B <servlet>
)B <servlet-name>login</servlet-name>
)B <servlet-class>com.onjava.login</servlet-class>
)B </servlet>
)B <taglib>
)B <taglib-uri>/onjava</taglib-uri>
)B <taglib-location>/WEB-INF/lib/taglib.tld</taglib-location>
)B </taglib>
</web-app>
The added <taglib>
entry contains two
elements. The first <taglib>
element,
<taglib-uri>
, tells the container how the tag
library is to be referenced. For this example we use the value
/onjava
, which is the way we'll reference the tag library
in our JSPs.
The second <taglib>
element,
<taglib-location>
, defines the location of the tag
library's descriptor (TLD). The TLD defines the tags contained in the
library and the handlers that will process the defined tags.
|
To complete your deployment, copy the compiled tag library and the
taglib.tld
into the
TOMCAT_ROOT/onjava/WEB-INF/lib
directory.
To test you new tag library, you need to modify the welcome.jsp
page, replacing the Welcome message with a reference to the
<onjava:hello />
tag. You need to also add a taglib
directive referencing the taglib.tld
to the
welcome.jsp
file. The modified JSP is in Listing 7.
Listing 7 Modified welcome.jsp
<%@ taglib uri="/onjava" prefix="onjava" %>
<html>
<head>
)B <title>Onjava Demo</title>
)B <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
)B <table width="500" border="0" cellspacing="0" cellpadding="0">
)B <tr>
)B <td> </td>
)B </tr>
)B <tr>
)B <td>
)B <img src="/onjava/images/monitor2.gif"></td>
)B <td>
)B <b><onjava:hello /> : <%= request.getAttribute("USER") %></b>
)B </td>
)B </tr>
)B <tr>
)B <td> </td>
)B </tr>
)B </table>
</body>
</html>
Now open the login.jsp
page as described previously
and run through the demo again. This time instead of Welcome:
Bob, you should see the message Hello: Bob.
When your web application is ready for deployment, you need to
package it for distribution. As we discussed previously in Java Web Applications,
web applications are packaged in WAR files. The steps required to
"WAR-up" your /onjava
web application and deploy it are
as follows:
Change to the root directory of your web application. In this case the root directory would be TOMCAT_HOME/webapps/onjava/
.
Archive the web application:
jar cvf onjava.war .
Copy the resulting WAR file, onjava.war
, to the
TOMCAT_HOME/webapps
directory.
If you're deploying this WAR file to the Tomcat installation that
you were developing in, then you will need to back up your development
directory and remove it from the TOMCAT_HOME/webapps
directory.
Add a new Context entry to the /TOMCAT_HOME/conf/server.xml
file, referencing the onjava web application.
Restart Tomcat.
That's it. Your application should now be deployed and running. If
it isn't, check your entry in the
TOMCAT_HOME/conf/server.xml
file to ensure that you have
set the appropriate values.
Now that you know how to create and deploy a web applications,
we'll examine the relationship of the web application and
its ServletContext
in a future article.
James Goodwill is the Co-Founder and Chief Architect of the Denver, Colorado based Virtuas Solutions, LLC.
Read more from Using Tomcat.
Return to ONJava.com.
oreillynet.com Copyright )B© 2000 O'Reilly & Associates, Inc.