Another major way of deploying a web application into Tomcat is to deploy the application packed into a WAR file. WAR files are described in detail in the Java Servlet Specification.
With Tomcat, when you deploy your WAR file, you must decide whether to serve your webapp after unpacking the WAR file or while it is still packed into a WAR file. Both ways are supported. By default, when Tomcat deploys a WAR file, the first thing it does is unpack the contents of the WAR file into a directory of the same name minus the .war extension, and then serves the files from the unpacked directory.
For example, if your WAR file is named suitcase.war
,
Tomcat would unpack the contents of suitcase.war
into a
directory named suitcase
, and then the files that are
served as part of the webapp will be read from the suitcase
directory on disk, not from the WAR file. You may turn off the
automatic unpacking behavior by setting unpackWARs="false"
on your Host
element in
server.xml. With it set to false
,
Tomcat will serve your webapp's files right from the packed WAR file itself.
There are two ways to configure Tomcat to recognize and start your web application when you first deploy it as a WAR file:
Add a <Context>
element to the
server.xml file and restart Tomcat.
Add a new context XML fragment file in Tomcat's
CATALINA_HOME/conf/[EngineName]
/[Hostname]
directory tree, or create it as your web application's
WEB-INF/context.xml file relative to the root directory of your
web application, then restart Tomcat.
For any given webapp, you should choose just one of these deployment configuration methods. In the next sections, we show you details about each deployment method.
You may edit your conf/server.xml file and configure Tomcat to recognize, start, and manage your web application. Again, this is the way we suggest you configure Tomcat for each new webapp you add.
To deploy your WAR file using this method of deployment, you must add a Context
element for your webapp in
server.xml and nest your webapp's Context
inside a Host
container
element.
Edit your server.xml file and search for a Host
element. By default, it will look like this:
<Host name="localhost" appBase="webapps"
unpackWARs="true
" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
...
</Host>
You may set the value of unpackWARs
to either
true
or false
,
depending on your decision to serve from the packed WAR, or to serve from an unpacked
directory after first unpacking it. We suggest you leave the value set to true
, and allow Tomcat to unpack your WAR file and serve your
files from the unpacked directory, because then you can more easily inspect what webapp
files and their content Tomcat is serving. See the "Hosts" section,
earlier in this chapter, for a more detailed explanation about why we suggest
this.
Usually, adding your Context
inside the default
Host
works because by default the default host's name
is localhost
, and any requests coming into your machine
via Tomcat's network server will (by default) be routed to the default host.
Add your Context
inside of the Host
like this:
<Host name="localhost" appBase="webapps" unpackWARs="true
" autoDeploy="false
" xmlValidation="false" xmlNamespaceAware="false"><Context docBase="
my-webapp
.war" path="
/my-webapp
"/>
</Host>
It is important to set autoDeploy="false"
on your
Host
element so that your webapp does not get
deployed twice. This can happen because it is deployed first by the Context
configuration in server.xml
(because deployOnStartup="true"
), and then also by
the automatic deployment that occurs when autoDeploy
is set to true
(by default, when these attributes are
not explicitly set on a Context
, they each default to
true
). Setting autoDeploy
to false
explicitly avoids
any duplicate deployment of the same webapp when you are adding your Context
configuration to
server.xml.
Save server.xml and restart Tomcat. When Tomcat comes back up, it
will look for your webapp's WAR file in the path
CATALINA_HOME/webapps/my-webapp
.war.
If Tomcat finds your webapp at that path, Tomcat will attempt to deploy your webapp, and
"mount" it on the web server URI path /my-webapp
. If Tomcat
doesn't encounter any errors deploying and starting your webapp (see the logs), it should
be accessible by browsing http://localhost:8080/my-webapp.
If, instead, you want this particular webapp to be mapped to the root URI ("/") of your server, such that by accessing http://localhost:8080 you see your webapp, you will need to perform some extra steps:
Stop Tomcat.
Make sure that there is no
CATALINA_HOME/conf/[EngineName]
/[Hostname]
/ROOT.xml
configuration file. If it exists, you should simply delete it.
Edit your server.xml file and make your Host
and Context
look
like this instead:
<Host name="localhost" appBase="webapps" unpackWARs="true
" autoDeploy="false
" xmlValidation="false" xmlNamespaceAware="false"><Context docBase="
my-webapp
.war" path=""/>
</Host>
Notice the path=""
on the Context
element; it tells Tomcat to map your webapp to the root URI path.
That way, no other webapp is already mapped to the root URI path, and your webapp is
explicitly mapped to the root URI path. Again, make sure autoDeploy
is set to false
, otherwise,
your webapp will be deployed twice (once on the root URI path by the explicit
configuration in server.xml and again on the "/
my-webapp
" URI by the automatic
deployer).
Restart Tomcat, and once it is done starting up, browse http://localhost:8080, and you should see your webapp.
Context entries can also appear as context XML fragment files. A context XML fragment
file is not a complete server.xml configuration file, but just one
Context
element and any subelements that are
appropriate for your web application, just as it would be configured in
server.xml except that the path
attribute cannot be specified when the Context
element
resides in a context XML fragment file.
Context XML fragment files can reside in either the
CATALINA_HOME/conf/[EngineName]
/[EngineName]
/[HostName]
/
directory tree, Tomcat reads the filename of the context XML fragment file and uses it as
the web server URI path to the webapp, just as if the path
attribute were set to the name of the file (minus the ".xml
" extension). For example, if the context XML fragment
file is named "my-webapp.xml
", when Tomcat deploys and
starts the webapp, it will be accessible via the URL http://localhost:8080/my-webapp.
The fact that you cannot set the path attribute of the Context
element in context XML fragment files is a disadvantage of
deploying your webapps this way in comparison to deploying them by adding a Context
element to the server.xml file.
If you deploy your webapp by adding a Context
element
to server.xml instead, you can set the path to anything you like.
In order to specify a different URI path, you must name the context XML fragment file
the path itself, like new-path.xml
, and that's not
very flexible. If you must map it to a new URI path that contains slashes, like
"/new/path/my-webapp
", there is a feature to allow
doing this. You can name your context XML fragment file "new#path#my-webapp.xml
" (notice the number signs where slashes would
otherwise be in the filename). But, we find this to be an inelegant solution because it
is not intuitive to system administrators or webapp developers who have not previously
seen this naming conventionāit is uncommon. This may also cause some problems with
writing and deploying web applications that have been localized for other locales where
the character set is different since it would necessitate naming a context XML fragment
file a name containing non-ISO-8859-1 characters that may not be printable or readable
when an administrator lists the directory contents of
CATALINA_HOME/conf/Catalina/localhost directory, for
example.
An example of context XML fragment file deployment is the Admin web application discussed in Chapter 2. It is not listed in the server.xml file; instead it is explicitly configured through a context XML element stored in the file CATALINA_HOME/conf/Catalina/localhost/admin.xml:
<!-- Context configuration file for the Tomcat Administration Web App $Id$ --> <Context docBase="${catalina.home}/server/webapps/admin" privileged="true" antiResourceLocking="false" antiJARLocking="false"> <!-- Uncomment this Valve to limit access to the Admin app to localhost for obvious security reasons. Allow may be a comma-separated list of hosts (or even regular expressions). <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1"/> --> </Context>
If you are trying to configure Tomcat's root webapp (where your webapp is accessible
at the URL http://localhost:8080) via a context XML fragment file, there is
a special rule you should know. Because the root URI could either be expressed as
"/
" or "" (an empty context path), this does not map
well to filenames, and Tomcat treats this as an exceptional case. If you are deploying via
a context XML fragment file in
CATALINA_HOME/conf/[EngineName]
/[HostName]
/,
you must name your context XML fragment file "ROOT.xml
", and Tomcat will map the context to the root URI. Or, if you're using
a META-INF/context.xml file to deploy your webapp on the root URI,
you need to name your webapp directory ROOT
.
As another example, if we wanted to deploy a webapp directory named
my-webapp that resides in a packed WAR file at the path /opt/webapps/
my-webapp
.war
on a local filesystem, along with configuring an
authentication realm for accessing parts of that web application, we could use this
context XML fragment file:
<!-- Context XML fragment file for deployingmy-webapp
. --> <Context docBase="/opt/webapps/my-webapp.war
"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Context>
Name the context XML fragment file "my-webapp
.xml
" and place it in the
CATALINA_HOME/conf/Catalina/localhost/ directory, restart Tomcat,
and Tomcat should find it and your webapp should be deployed.
Note that in these examples, we are providing the Context
XML configuration element; you can specify all the Context
values that you need in the context's XML fragment
file. Also, in the above example, we show a Realm
configuration that uses Tomcat's UserDatabaseRealm
to
authenticate against the users and roles stored in the
CATALINA_HOME/conf/tomcat-users.xml file. This demonstrates that it
is okay to nest any of the same configuration elements inside the Context
element of a context XML fragment file, just as you would if you were
to configure the Context
inside Tomcat's
server.xml file. For more information about Realm
s, see the "Realms" section in Chapter
2.
If you wish to place your context XML fragment file inside the webapp itself, you must
place it in the path META-INF/context.xml.[17] This name cannot change as Tomcat will only look for a context XML fragment
file of that exact name. The disadvantage to this is that you cannot set the Context
's path attribute inside the
META-INF/context.xml file, plus you cannot change the filename, so
you do not have a way of changing the URI path to which Tomcat maps the webapp; it's
simply the name of the webapp's WAR file, minus the ".xml
" file extension. If that is acceptable, the advantage to using this
configuration file is that it rides inside the webapp itself and is not an additional file
that has to be installed separately. For Tomcat to read and use your
META-INF/context.xml file, you must not set
deployXML="false"
on your Host
. By default, it is set to true
, so if
you do not explicitly set it, Tomcat will use the context.xml file if
it exists.
Before you decide to use this deployment method, keep in mind that one of the initial
reasons the Tomcat developers chose to offer the feature of context XML fragment files was
so that web applications could be configured with configuration files separately from
server.xml (so that server.xml would not need
to be so frequently modified). The main idea here was to make the webapp configuration
modular and separate from the rest of the Tomcat configuration. But, usually webapps need
more configuration than just the Context
element and
what it contains. Webapps often also need custom Connector
configuration, custom Host
configuration (at least some deployment attributes usually change, but sometimes also the
Host
's name must change, possibly requiring the
Engine
's default host name to change), custom
GlobalNamingResources
configuration, etc. These are
all outside the scope of the Context
element and cannot
be configured inside a context XML fragment file. That means you still have to modify
server.xml to configure common webapp-specific items, so the
webapp's configuration cannot usually be kept cleanly separate from the rest of Tomcat's
configuration in server.xml.
[17] * Again, this is a Tomcat-specific configuration file in an otherwise servlet-container-implementation-independent webapp tree. It will work for Tomcat, but because this feature is not part of the Java Servlet Specification, the context.xml file will probably not be read nor used by any other servlet container.
3.143.1.57