UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

369 lines (367 loc) 71.1 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>WAR Files and Deployment</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="WAR Files and Deployment"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-15-SECT-3"/>WAR Files and Deployment</h1></div></div></div><p>As we described in the introduction to this chapter, a WAR file is an archive that contains all the parts of a web application: Java class files for servlets and web services, JSPs, HTML pages, images, and other resources. The WAR file is simply a JAR file (which is itself a fancy ZIP file) with specified directories for the Java code and one designated configuration file: the <span class="emphasis"><em>web.xml</em></span> file, which tells the application server what to run and how to run it. WAR files always have the extension <span class="emphasis"><em>.war</em></span>, but they can be created and read with the standard <span class="emphasis"><em>jar</em></span> tool.</p><p>The contents of a typical WAR might look like this, as revealed by the <span class="emphasis"><em>jar</em></span> tool:</p><a id="I_15_tt932"/><pre class="programlisting"> <code class="n">$</code> <strong class="userinput"><code><code class="n">jar</code> <code class="n">tvf</code> <code class="n">shoppingcart</code><code class="o">.</code><code class="na">war</code></code></strong> <code class="n">index</code><code class="o">.</code><code class="na">html</code> <code class="n">purchase</code><code class="o">.</code><code class="na">html</code> <code class="n">receipt</code><code class="o">.</code><code class="na">html</code> <code class="n">images</code><code class="o">/</code><code class="n">happybunny</code><code class="o">.</code><code class="na">gif</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code><code class="o">/</code><code class="n">web</code><code class="o">.</code><code class="na">xml</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code><code class="o">/</code><code class="n">classes</code><code class="o">/</code><code class="n">com</code><code class="o">/</code><code class="n">mycompany</code><code class="o">/</code><code class="n">PurchaseServlet</code><code class="o">.</code><code class="na">class</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code><code class="o">/</code><code class="n">classes</code><code class="o">/</code><code class="n">com</code><code class="o">/</code><code class="n">mycompany</code><code class="o">/</code><code class="n">ReturnServlet</code><code class="o">.</code><code class="na">class</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code><code class="o">/</code><code class="n">lib</code><code class="o">/</code><code class="n">thirdparty</code><code class="o">.</code><code class="na">jar</code></pre><p>When deployed, the name of the WAR becomes, by default, the root path of the web application—in this case, <span class="emphasis"><em>shoppingcart</em></span>. Thus, the base URL for this web app, if deployed on <span class="emphasis"><em>http://www.oreilly.com</em></span>, is <span class="emphasis"><em>http://www.oreilly.com/shoppingcart/</em></span>, and all references to its documents, images, and servlets start with that path. The top level of the WAR file becomes the document root (base directory) for serving files. Our <span class="emphasis"><em>index.html</em></span> file appears at the base URL we just mentioned, and our <span class="emphasis"><em>happybunny.gif</em></span> image is referenced as <span class="emphasis"><em>http://www.oreilly.com/shoppingcart/images/happybunny.gif.</em></span></p><p>The <a id="I_indexterm15_id779820" class="indexterm"/><span class="emphasis"><em>WEB-INF</em></span> directory (all caps, hyphenated) is a special directory that contains all deployment information and application code. This directory is protected by the web server, and its contents are not visible to outside users of the application, even if you add <span class="emphasis"><em>WEB-INF</em></span> to the base URL. Your application classes can load additional files from this area using <code class="literal">getResource()</code> on the servlet context, however, so it is a safe place to store application resources. The <span class="emphasis"><em>WEB-INF</em></span> directory also contains the <span class="emphasis"><em>web.xml</em></span> file, which we’ll talk more about in the next section.</p><p>The <a id="I_indexterm15_id779852" class="indexterm"/><span class="emphasis"><em>WEB-INF/classes</em></span> and <a id="I_indexterm15_id779860" class="indexterm"/><span class="emphasis"><em>WEB-INF/lib</em></span> directories contain Java class files and JAR libraries, respectively. The <span class="emphasis"><em>WEB-INF/classes</em></span> directory is automatically added to the classpath of the web application, so any class files placed here (using the normal Java package conventions) are available to the application. After that, any JAR files located in <span class="emphasis"><em>WEB-INF/lib</em></span> are appended to the web app’s classpath (the order in which they are appended is, unfortunately, not specified). You can place your classes in either location. During development, it is often easier to work with the “loose” <span class="emphasis"><em>classes</em></span> directory and use the <span class="emphasis"><em>lib</em></span> directory for supporting classes and third-party tools. It’s also possible to install JAR files directly in the servlet container to make them available to all web apps running on that server. This is often done for common libraries that will be used by many web apps. The location for placing the libraries, however, is not standard and any classes that are deployed in this way cannot be automatically reloaded if changed—a feature of WAR files that we’ll discuss later. Servlet API requires that each server provide a directory for these extension JARs and that the classes there will be loaded by a single classloader and made visible to the web application.</p><div class="sect2" title="Configuration with web.xml and Annotations"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-15-SECT-3.1"/>Configuration with web.xml and Annotations</h2></div></div></div><p><a id="idx10879" class="indexterm"/> <a id="idx10901" class="indexterm"/> <a id="idx10910" class="indexterm"/>The <span class="emphasis"><em>web.xml</em></span> file is an XML configuration file that lists servlets and related entities to be deployed, the relative names (URL paths) under which to deploy them, their initialization parameters, and their deployment details, including security and authorization. For most of the history of Java web applications, this was the only deployment configuration mechanism. However, as of the Servlet 3.0 API, there are additional options. Most configuration can now be done using Java annotations. We saw the WebServlet annotation used in the first example, <code class="literal">HelloClient</code>, to declare the servlet and specify its deployment URL path. Using the annotation, we could deploy the servlet to the Tomcat server without any <span class="emphasis"><em>web.xml</em></span> file. Another option with the Servlet 3.0 API is to deploy servlet procedurally—using Java code at runtime.</p><p>In this section we will describe both the XML and annotation style of configuration. For most purposes, you will find it easier to use the annotations, but there are a couple of reasons to understand the XML configuration as well. First, the <span class="emphasis"><em>web.xml</em></span> can be used to override or extend the hardcoded annotation configuration. Using the XML, you can change configuration at deployment time without recompiling the classes. In general, configuration in the XML will take precedence over the annotations. It is also possible to tell the server to ignore the annotations completely, using an attribute called <a id="I_indexterm15_id779978" class="indexterm"/><code class="literal">metadata-complete</code> in the <span class="emphasis"><em>web.xml</em></span>. Next, there may be some residual configuration, especially relating to options of the servlet container, which can only be done through XML.</p><p>We will assume that you have at least a passing familiarity with XML, but you can simply copy these examples in a cut-and-paste fashion. (For details about working with Java and XML, see <a class="xref" href="ch24.html" title="Chapter 24. XML">Chapter 24</a>.) Let’s start with a simple <span class="emphasis"><em>web.xml</em></span> file for our <code class="literal">HelloClient</code> servlet example. It looks like this:</p><a id="I_15_tt933"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">web</code><code class="o">-</code><code class="n">app</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">helloclient1</code><code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">class</code><code class="o">&gt;</code><code class="n">HelloClient</code><code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">class</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">servlet</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">mapping</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">helloclient1</code><code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">url</code><code class="o">-</code><code class="n">pattern</code><code class="o">&gt;/</code><code class="n">hello</code><code class="o">&lt;/</code><code class="n">url</code><code class="o">-</code><code class="n">pattern</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">mapping</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">web</code><code class="o">-</code><code class="n">app</code><code class="o">&gt;</code></pre><p>The top-level element of the document is called <code class="literal">&lt;web-app&gt;</code>. Many types of entries may appear inside the <code class="literal">&lt;web-app&gt;</code>, but the most basic are <a id="I_indexterm15_id780039" class="indexterm"/><code class="literal">&lt;servlet&gt;</code> declarations and <a id="I_indexterm15_id780052" class="indexterm"/><code class="literal">&lt;servlet-mapping&gt;</code> deployment mappings. The <code class="literal">&lt;servlet&gt;</code> declaration tag is used to declare an instance of a servlet and, optionally, to give it initialization and other parameters. One instance of the servlet class is instantiated for each <code class="literal">&lt;servlet&gt;</code> tag appearing in the <span class="emphasis"><em>web.xml</em></span> file.</p><p>At minimum, the <code class="literal">&lt;servlet&gt;</code> declaration requires two pieces of information: a <a id="I_indexterm15_id780092" class="indexterm"/><code class="literal">&lt;servlet-name&gt;</code>, which serves as a handle to reference the servlet elsewhere in the <span class="emphasis"><em>web.xml</em></span> file, and the <a id="I_indexterm15_id780110" class="indexterm"/><code class="literal">&lt;servlet-class&gt;</code> tag, which specifies the Java class name of the servlet. Here, we named the servlet <code class="literal">helloclient1</code>. We named it like this to emphasize that we could declare other instances of the same servlet if we wanted to, possibly giving them different initialization parameters, etc. The class name for our servlet is, of course, <code class="literal">HelloClient</code>. In a real application, the servlet class would likely have a full package name, such as <code class="literal">com.oreilly.servlets.HelloClient</code>.</p><p>A servlet declaration may also include one or more initialization parameters, which are made available to the servlet through the <code class="literal">ServletConfig</code> object’s <code class="literal">getInitParameter()</code> method:</p><a id="I_15_tt934"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">helloclient1</code><code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">class</code><code class="o">&gt;</code><code class="n">HelloClient</code><code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">class</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">init</code><code class="o">-</code><code class="n">param</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">param</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">foo</code><code class="o">&lt;/</code><code class="n">param</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">param</code><code class="o">-</code><code class="n">value</code><code class="o">&gt;</code><code class="n">bar</code><code class="o">&lt;/</code><code class="n">param</code><code class="o">-</code><code class="n">value</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">init</code><code class="o">-</code><code class="n">param</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">servlet</code><code class="o">&gt;</code></pre><p>Next, we have our <code class="literal">&lt;servlet-mapping&gt;</code>, which associates the servlet instance with a path on the web server:</p><a id="I_15_tt935"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">mapping</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">helloclient1</code><code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">url</code><code class="o">-</code><code class="n">pattern</code><code class="o">&gt;/</code><code class="n">hello</code><code class="o">&lt;/</code><code class="n">url</code><code class="o">-</code><code class="n">pattern</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">servlet</code><code class="o">-</code><code class="n">mapping</code><code class="o">&gt;</code></pre><p>Here we mapped our servlet to the path <span class="emphasis"><em>/hello</em></span>. (We could include additional url-patterns in the mapping if desired.) If we later name our WAR <span class="emphasis"><em>learningjava.war</em></span> and deploy it on <span class="emphasis"><em>www.oreilly.com</em></span>, the full path to this servlet would be <span class="emphasis"><em>http://www.oreilly.com/learningjava/hello</em></span>. Just as we could declare more than one servlet instance with the <code class="literal">&lt;servlet&gt;</code> tag, we could declare more than one <code class="literal">&lt;servlet-mapping&gt;</code> for a given servlet instance. We could, for example, redundantly map the same <code class="literal">helloclient1</code> instance to the paths <span class="emphasis"><em>/hello</em></span> and <span class="emphasis"><em>/hola</em></span>. The <code class="literal">&lt;url-pattern&gt;</code> tag provides some very flexible ways to specify the URLs that should match a servlet. We’ll talk about this in detail in the next section.</p><p>Finally, we should mention that although the <span class="emphasis"><em>web.xml</em></span> example listed earlier will work on some application servers, it is technically incomplete because it is missing formal information that specifies the version of XML it is using and the version of the <span class="emphasis"><em>web.xml</em></span> file standard with which it complies. To make it fully compliant with the standards, add a line such as:</p><a id="I_15_tt936"/><pre class="programlisting"> <code class="o">&lt;?</code><code class="n">xml</code> <code class="n">version</code><code class="o">=</code><code class="s">"1.0"</code> <code class="n">encoding</code><code class="o">=</code><code class="s">"ISO-8859-1"</code><code class="o">?&gt;</code></pre><p>As of Servlet API 2.5, the <span class="emphasis"><em>web.xml</em></span> version information takes advantage of XML Schemas. (We’ll talk about XML DTDs and XML Schemas in <a class="xref" href="ch24.html" title="Chapter 24. XML">Chapter 24</a>.) The additional information is inserted into the <code class="literal">&lt;web-app&gt;</code> element:</p><a id="I_15_tt938"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">web</code><code class="o">-</code><code class="n">app</code> <code class="n">xmlns</code><code class="o">=</code><code class="s">"http://java.sun.com/xml/ns/j2ee"</code> <code class="nl">xmlns:</code><code class="n">xsi</code><code class="o">=</code><code class="s">"http://www.w3.org/2001/XMLSchema-instance"</code> <code class="nl">xsi:</code><code class="n">schemaLocation</code><code class="o">=</code><code class="err">"</code><code class="nl">http:</code><code class="c1">//java.sun.com/xml/ns/j2ee</code> <code class="nl">http:</code><code class="c1">//java.sun.com/xml/ns/j2ee/web-app_2_5.xsd”</code> <code class="n">version</code><code class="o">=</code><code class="err">”</code><code class="mf">2.5</code><code class="err">”</code><code class="o">&gt;</code></pre><p>If you leave them out, the application may still run, but it will be harder for the servlet container to detect errors in your configuration and give you clear error messages.</p><p>The equivalent of the preceding servlet declaration and mapping is, as we saw earlier, our one line annotation:</p><a id="I_programlisting15_id780311"/><pre class="programlisting"><code class="nd">@WebServlet</code><code class="o">(</code><code class="n">urlPatterns</code><code class="o">={</code><code class="s">"/hello"</code><code class="o">,</code> <code class="s">"/hola"</code><code class="o">})</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">HelloClient</code> <code class="kd">extends</code> <code class="n">HttpServlet</code> <code class="o">{</code> <code class="o">...</code> <code class="o">}</code></pre><p>Here the <code class="literal">WebServlet</code> attribute <a id="I_indexterm15_id780326" class="indexterm"/><code class="literal">urlPatterns</code> allows us to specify one or more URL patterns that are the equivalent to the <code class="literal">url-pattern</code> declaration in the <span class="emphasis"><em>web.xml.</em></span><a id="I_indexterm15_id780345" class="indexterm"/><a id="I_indexterm15_id780352" class="indexterm"/><a id="I_indexterm15_id780359" class="indexterm"/></p></div><div class="sect2" title="URL Pattern Mappings"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-15-SECT-3.2"/>URL Pattern Mappings</h2></div></div></div><p><a id="idx10873" class="indexterm"/> <a id="idx10874" class="indexterm"/> <a id="idx10884" class="indexterm"/> <a id="idx10906" class="indexterm"/>The <a id="I_indexterm15_id780423" class="indexterm"/><code class="literal">&lt;url-pattern&gt;</code> specified in the previous example was a simple string, <code class="literal">/hello</code>. For this pattern, only an exact match of the base URL followed by <code class="literal">/hello</code> would invoke our servlet. The <code class="literal">&lt;url-pattern&gt;</code> tag is capable of more powerful patterns, however, including wildcards. For example, specifying a <code class="literal">&lt;url-pattern&gt;</code> of <code class="literal">/hello*</code> allows our servlet to be invoked by URLs such as <span class="emphasis"><em>http://www.oreilly.com/learningjava/helloworld</em></span> or <code class="literal">.../hellobaby</code>. You can even specify wildcards with extensions (e.g., <code class="literal">*.html</code> or <code class="literal">*.foo</code>, meaning that the servlet is invoked for any path that ends with those characters).</p><p>Using wildcards can result in more than one match. Consider URLs ending in <code class="literal">/scooby*</code> and <code class="literal">/scoobydoo*</code>. Which should be matched for a URL ending in <code class="literal">.../scoobydoobiedoo</code>? What if we have a third possible match because of a wildcard suffix extension mapping? The rules for resolving these are as follows.</p><p>First, any exact match is taken. For example, <code class="literal">/hello</code> matches the <code class="literal">/hello</code> URL pattern in our example regardless of any additional <code class="literal">/hello*</code>. Failing that, the container looks for the longest prefix match. So <code class="literal">/scoobydoobiedoo</code> matches the second pattern, <code class="literal">/scoobydoo*</code>, because it is longer and presumably more specific. Failing any matches there, the container looks at wildcard suffix mappings. A request ending in <code class="literal">.foo</code> matches a <code class="literal">*.foo</code> mapping at this point in the process. Finally, failing any matches there, the container looks for a default, catchall mapping named <code class="literal">/*</code>. A servlet mapped to <code class="literal">/*</code> picks up anything unmatched by this point. If there is no default servlet mapping, the request fails with a “404 not found” message.<a id="I_indexterm15_id780566" class="indexterm"/><a id="I_indexterm15_id780573" class="indexterm"/><a id="I_indexterm15_id780580" class="indexterm"/><a id="I_indexterm15_id780587" class="indexterm"/></p></div><div class="sect2" title="Deploying HelloClient"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-15-SECT-3.3"/>Deploying HelloClient</h2></div></div></div><p><a id="idx10850" class="indexterm"/> <a id="idx10880" class="indexterm"/> <a id="idx10902" class="indexterm"/>Once you’ve deployed the <code class="literal">HelloClient</code> servlet, it should be easy to add examples to the WAR as you work with them in this chapter. In this section, we’ll show you how to build a WAR by hand. In “Building WAR Files with Ant” later in this chapter, we’ll show a more realistic way to manage your applications using the popular build tool, Ant. You can also grab the full set of examples, along with their source code, in the <span class="emphasis"><em>learningjava.war</em></span> file from this book’s website at <a class="ulink" href="http://oreil.ly/Java_4E">http://oreil.ly/Java_4E</a>.</p><p>To create the WAR by hand, we first create the <span class="emphasis"><em>WEB-INF</em></span> and <span class="emphasis"><em>WEB-INF/classes</em></span> directories. If you are using a <span class="emphasis"><em>web.xml</em></span> file, place it into <span class="emphasis"><em>WEB-INF</em></span>. Put the <span class="emphasis"><em>HelloClient.class</em></span> into <span class="emphasis"><em>WEB-INF/classes</em></span>. Use the <a id="I_indexterm15_id780691" class="indexterm"/><span class="emphasis"><em>jar</em></span> command to create <span class="emphasis"><em>learningjava.war</em></span> (WEB-INF at the “top” level of the archive):</p><a id="I_15_tt939"/><pre class="programlisting"> <code class="n">$</code> <strong class="userinput"><code><code class="n">jar</code> <code class="n">cvf</code> <code class="n">learningjava</code><code class="o">.</code><code class="na">war</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code></code></strong></pre><p>You can also include documents and other resources in the WAR by adding their names after the <span class="emphasis"><em>WEB-INF</em></span> directory. This command produces the file <span class="emphasis"><em>learningjava.war</em></span>. You can verify the contents using the <span class="emphasis"><em>jar</em></span> command:</p><a id="I_15_tt940"/><pre class="programlisting"> <code class="n">$</code> <strong class="userinput"><code><code class="n">jar</code> <code class="n">tvf</code> <code class="n">learningjava</code><code class="o">.</code><code class="na">war</code></code></strong> <code class="n">document1</code><code class="o">.</code><code class="na">html</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code><code class="o">/</code><code class="n">web</code><code class="o">.</code><code class="na">xml</code> <code class="n">WEB</code><code class="o">-</code><code class="n">INF</code><code class="o">/</code><code class="n">classes</code><code class="o">/</code><code class="n">HelloClient</code><code class="o">.</code><code class="na">class</code></pre><p><a id="I_indexterm15_id780746" class="indexterm"/>Now all that is necessary is to drop the WAR into the correct location for your server. If you have not already, you should download and install Apache Tomcat. The location for WAR files is the <a id="I_indexterm15_id780755" class="indexterm"/><span class="emphasis"><em>webapps</em></span> directory within your Tomcat installation directory. Place your WAR here, and start the server. If Tomcat is configured with the default port number, you should be able to point to the <code class="literal">HelloClient</code> servlet with one of two URLs: <span class="emphasis"><em>http://localhost:8080/learningjava/hello</em></span> or <span class="emphasis"><em>http://<em class="replaceable"><code>&lt;yourserver&gt;</code></em>:8080/learningjava/hello</em></span>, where <em class="replaceable"><code>&lt;yourserver&gt;</code></em> is the name or IP address of your server. If you have trouble, look in the <a id="I_indexterm15_id780789" class="indexterm"/><span class="emphasis"><em>logs</em></span> directory of the Tomcat folder for errors.</p><div class="sect3" title="Reloading web apps"><div class="titlepage"><div><div><h3 class="title"><a id="learnjava3-CHP-15-SECT-3.3.1"/>Reloading web apps</h3></div></div></div><p><a id="idx10856" class="indexterm"/> <a id="idx10886" class="indexterm"/>All servlet containers are supposed to provide a facility for reloading WAR files; many support reloading of individual servlet classes after they have been modified. Reloading WARs is part of the servlet specification and is especially useful during development. Support for reloading web apps varies from server to server. Normally, all that you have to do is drop a new WAR in place of the old one in the proper location (e.g., the <span class="emphasis"><em>webapps</em></span> directory for Tomcat) and the container shuts down the old application and deploys the new version. This works in Tomcat when the “autoDeploy” attribute is set (it is on by default) and also in BEA’s WebLogic application server when it is configured in development mode.</p><p>Some servers, including Tomcat, “explode” WARs by unpacking them into a directory under the <span class="emphasis"><em>webapps</em></span> directory, or they allow you explicitly to configure a root directory (or “context”) for your unpacked web app through their own configuration files. In this mode, they may allow you to replace individual files, which can be especially useful for tweaking HTML or JSPs. Tomcat automatically reloads WAR files when they change them (unless configured not to), so all you have to do is drop an updated WAR over the old one and it will redeploy it as necessary. In some cases, it may be necessary to restart the server to make all changes take effect. When in doubt, shut down and restart.</p><p>Tomcat also provides a client-side “deployer” package that integrates with Ant to automate building, deploying, and redeploying applications. We’ll discuss Ant later in this chapter.<a id="I_indexterm15_id780860" class="indexterm"/><a id="I_indexterm15_id780867" class="indexterm"/><a id="I_indexterm15_id780874" class="indexterm"/><a id="I_indexterm15_id780881" class="indexterm"/><a id="I_indexterm15_id780888" class="indexterm"/></p></div></div><div class="sect2" title="Error and Index Pages"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-15-SECT-3.4"/>Error and Index Pages</h2></div></div></div><p><a id="idx10848" class="indexterm"/> <a id="idx10881" class="indexterm"/> <a id="idx10903" class="indexterm"/>One of the finer points of writing a professional-looking web application is taking care to handle errors well. Nothing annoys a user more than getting a funny-looking page with some technical mumbo-jumbo error information on it when he expected the receipt for his Christmas present. Through the <span class="emphasis"><em>web.xml</em></span> file, it is possible to specify documents or servlets to handle error pages that are shown for various conditions, as well as the special case of <span class="emphasis"><em>welcome files</em></span> (index files) that are invoked for paths corresponding to directories. At this time, there is no corresponding way to declare error pages or welcome files using annotations.</p><p>You can designate a page or servlet that can handle various HTTP error status codes, such as “404 Not Found” and “403 Forbidden,” using one or more <a id="I_indexterm15_id780959" class="indexterm"/><code class="literal">&lt;error-page&gt;</code>declarations:</p><a id="I_15_tt941"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">web</code><code class="o">-</code><code class="n">app</code><code class="o">&gt;</code> <code class="o">...</code> <code class="o">&lt;</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">error</code><code class="o">-</code><code class="n">code</code><code class="o">&gt;</code><code class="mi">404</code><code class="o">&lt;/</code><code class="n">error</code><code class="o">-</code><code class="n">code</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">location</code><code class="o">&gt;/</code><code class="n">notfound</code><code class="o">.</code><code class="na">html</code><code class="o">&lt;/</code><code class="n">location</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">error</code><code class="o">-</code><code class="n">code</code><code class="o">&gt;</code><code class="mi">403</code><code class="o">&lt;/</code><code class="n">error</code><code class="o">-</code><code class="n">code</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">location</code><code class="o">&gt;/</code><code class="n">secret</code><code class="o">.</code><code class="na">html</code><code class="o">&lt;/</code><code class="n">location</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code></pre><p>Additionally, you can designate error pages based on Java exception types that may be thrown from the servlet. For example:</p><a id="I_15_tt942"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">exception</code><code class="o">-</code><code class="n">type</code><code class="o">&gt;</code><code class="n">java</code><code class="o">.</code><code class="na">lang</code><code class="o">.</code><code class="na">IOException</code><code class="o">&lt;/</code><code class="n">exception</code><code class="o">-</code><code class="n">type</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">location</code><code class="o">&gt;/</code><code class="n">ioexception</code><code class="o">.</code><code class="na">html</code><code class="o">&lt;/</code><code class="n">location</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code></pre><p>This declaration catches any <a id="I_indexterm15_id781005" class="indexterm"/><code class="literal">IOException</code>s generated from servlets in the web app and displays the <span class="emphasis"><em>ioexception.html</em></span> page. If no matching exceptions are found in the <code class="literal">&lt;error-page&gt;</code> declarations, and the exception is of type <a id="I_indexterm15_id781026" class="indexterm"/><code class="literal">ServletException</code> (or a subclass), the container makes a second try to find the correct handler. It looks for a wrapped exception (the “cause” exception) contained in the <code class="literal">ServletException</code> and attempts to match it to an error page declaration.</p><p>In the Servlet 3.0 API, you can also designate a catchall error page that will handle any unhandled error codes and exception types as follows:</p><a id="I_programlisting15_id781050"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">location</code><code class="o">&gt;/</code><code class="n">anyerror</code><code class="o">.</code><code class="na">html</code><code class="o">&lt;/</code><code class="n">location</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">error</code><code class="o">-</code><code class="n">page</code><code class="o">&gt;</code></pre><p>As we’ve mentioned, you can use a servlet to handle your error pages, just as you can use a static document. In fact, the container supplies several helpful pieces of information to an error-handling servlet, which the servlet can use in generating a response. The information is made available in the form of servlet request attributes through the method <code class="literal">getAttribute()</code>:</p><a id="I_15_tt943"/><pre class="programlisting"> <code class="n">Object</code> <code class="n">requestAttribute</code> <code class="o">=</code> <code class="n">servletRequest</code><code class="o">.</code><code class="na">getAttribute</code><code class="o">(</code><code class="s">"name"</code><code class="o">);</code></pre><p>Attributes are like servlet parameters, except that they can be arbitrary objects. We have seen attributes of the <code class="literal">ServletContext</code> in <a class="xref" href="ch15s02.html#learnjava3-CHP-15-SECT-2.11" title="The ServletContext API">The ServletContext API</a> section. In this case, we are talking about attributes of the request. When a servlet (or JSP or filter) is invoked to handle an error condition, the following string attributes are set in the request:</p><a id="I_15_tt944"/><pre class="programlisting"> <code class="n">javax</code><code class="o">.</code><code class="na">servlet</code><code class="o">.</code><code class="na">error</code><code class="o">.</code><code class="na">servlet_name</code> <code class="n">javax</code><code class="o">.</code><code class="na">servlet</code><code class="o">.</code><code class="na">error</code><code class="o">.</code><code class="na">request_uri</code> <code class="n">javax</code><code class="o">.</code><code class="na">servlet</code><code class="o">.</code><code class="na">error</code><code class="o">.</code><code class="na">message</code></pre><p>Depending on whether the <a id="I_indexterm15_id781105" class="indexterm"/><code class="literal">&lt;error-page&gt;</code> declaration was based on an <a id="I_indexterm15_id781119" class="indexterm"/><code class="literal">&lt;error-code&gt;</code> or <a id="I_indexterm15_id781133" class="indexterm"/><code class="literal">&lt;exception-type&gt;</code> condition, the request also contains one of the following two attributes:</p><a id="I_15_tt945"/><pre class="programlisting"> <code class="c1">// status code Integer or Exception object</code> <code class="n">javax</code><code class="o">.</code><code class="na">servlet</code><code class="o">.</code><code class="na">error</code><code class="o">.</code><code class="na">status_code</code> <code class="n">javax</code><code class="o">.</code><code class="na">servlet</code><code class="o">.</code><code class="na">error</code><code class="o">.</code><code class="na">exception</code></pre><p>In the case of a status code, the attribute is an <code class="literal">Integer</code> representing the code. In the case of the exception type, the object is the actual instigating exception.</p><p>Indexes for directory paths can be designated in a similar way. Normally, when a user specifies a directory URL path, the web server searches for a default file in that directory to be displayed. The most common example of this is the ubiquitous <span class="emphasis"><em>index.html</em></span> file. You can designate your own ordered list of files to look for by adding a <a id="I_indexterm15_id781175" class="indexterm"/><code class="literal">&lt;welcome-file-list&gt;</code> entry to your <span class="emphasis"><em>web.xml</em></span> file. For example:</p><a id="I_15_tt946"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">welcome</code><code class="o">-</code><code class="n">file</code><code class="o">-</code><code class="n">list</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">welcome</code><code class="o">-</code><code class="n">file</code><code class="o">&gt;</code><code class="n">index</code><code class="o">.</code><code class="na">html</code><code class="o">&lt;/</code><code class="n">welcome</code><code class="o">-</code><code class="n">file</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">welcome</code><code class="o">-</code><code class="n">file</code><code class="o">&gt;</code><code class="n">index</code><code class="o">.</code><code class="na">htm</code><code class="o">&lt;/</code><code class="n">welcome</code><code class="o">-</code><code class="n">file</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">welcome</code><code class="o">-</code><code class="n">file</code><code class="o">-</code><code class="n">list</code><code class="o">&gt;</code></pre><p><code class="literal">&lt;welcome-file-list&gt;</code> specifies that when a partial request (directory path) is received, the server should search first for a file named <span class="emphasis"><em>index.html</em></span> and, if that is not found, a file called <span class="emphasis"><em>index.htm</em></span>. If none of the specified welcome files is found, it is left up to the server to decide what kind of page to display. Servers are generally configured to display a directory-like listing or to produce an error message.<a id="I_indexterm15_id781220" class="indexterm"/><a id="I_indexterm15_id781227" class="indexterm"/><a id="I_indexterm15_id781234" class="indexterm"/></p></div><div class="sect2" title="Security and Authentication"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-15-SECT-3.5"/>Security and Authentication</h2></div></div></div><p><a id="I_indexterm15_id781248" class="indexterm"/> <a id="I_indexterm15_id781257" class="indexterm"/>One of the most powerful features of web app deployment with the Servlet API is the ability to define <span class="emphasis"><em>declarative security</em></span> constraints, meaning that you can spell out in the <span class="emphasis"><em>web.xml</em></span> file exactly which areas of your web app (URL paths to documents, directories, servlets, etc.) are login-protected, the types of users allowed access to them, and the class of security protocol required for communications. It is not necessary to write code in your servlets to implement these basic security procedures.</p><p>There are two types of entries in the <span class="emphasis"><em>web.xml</em></span> file that control security and authentication. First are the <a id="I_indexterm15_id781287" class="indexterm"/><code class="literal">&lt;security-constraint&gt;</code> entries, which provide authorization based on user roles and secure transport of data, if desired. Second is the <a id="I_indexterm15_id781302" class="indexterm"/><code class="literal">&lt;login-config&gt;</code> entry, which determines the kind of authentication used for the web application.</p></div><div class="sect2" title="Protecting Resources with Roles"><div class="titlepage"><div><div><h2 class="title"><a id="learnjava3-CHP-15-SECT-3.6"/>Protecting Resources with Roles</h2></div></div></div><p><a id="idx10857" class="indexterm"/> <a id="idx10883" class="indexterm"/> <a id="idx10905" class="indexterm"/>Let’s take a look at a simple example. The following <span class="emphasis"><em>web.xml</em></span> excerpt defines an area called “Secret documents” with a URL pattern of <a id="I_indexterm15_id781368" class="indexterm"/><span class="emphasis"><em>/secret/*</em></span> and designates that only users with the role “secretagent” may access them. It specifies the simplest form of login process: the BASIC authentication model, which causes the browser to prompt the user with a simple pop-up username and password dialog box:</p><a id="I_15_tt947"/><pre class="programlisting"> <code class="o">&lt;</code><code class="n">web</code><code class="o">-</code><code class="n">app</code><code class="o">&gt;</code> <code class="o">...</code> <code class="o">&lt;</code><code class="n">security</code><code class="o">-</code><code class="n">constraint</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">web</code><code class="o">-</code><code class="n">resource</code><code class="o">-</code><code class="n">collection</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">web</code><code class="o">-</code><code class="n">resource</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">Secret</code> <code class="n">documents</code><code class="o">&lt;/</code><code class="n">web</code><code class="o">-</code><code class="n">resource</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">url</code><code class="o">-</code><code class="n">pattern</code><code class="o">&gt;/</code><code class="n">secret</code><code class="o">/*&lt;/</code><code class="n">url</code><code class="o">-</code><code class="n">pattern</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">web</code><code class="o">-</code><code class="n">resource</code><code class="o">-</code><code class="n">collection</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">auth</code><code class="o">-</code><code class="n">constraint</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">role</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code><code class="n">secretagent</code><code class="o">&lt;/</code><code class="n">role</code><code class="o">-</code><code class="n">name</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">auth</code><code class="o">-</code><code class="n">constraint</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">security</code><code class="o">-</code><code class="n">constraint</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">login</code><code class="o">-</code><code class="n">config</code><code class="o">&gt;</code> <code class="o">&lt;</code><code class="n">auth</code><code class="o">-</code><code class="n">method</code><code class="o">&gt;</code><code class="n">BASIC</code><code class="o">&lt;/</code><code class="n">auth</code><code class="o">-</code><code class="n">method</code><code class="o">&gt;</code> <code class="o">&lt;/</code><code class="n">login</code><code class="o">-</code><code class="n">config</code><code class="o">&gt;</code></pre><p>Each <a id="I_indexterm15_id781402" class="indexterm"/><code class="literal">&lt;security-constraint&gt;</code> block has one <a id="I_indexterm15_id781416" class="indexterm"/><code class="literal">&lt;web-resource-collection&gt;</code> section that designates a named list of URL patterns for areas of the web app, followed by an <a id="I_indexterm15_id781431" class="indexterm"/><code class="literal">&lt;auth-constraint&gt;</code> section listing user roles that are allowed to access those areas.</p><p>We can do the equivalent configuration for a given servlet using the SecurityServlet annotation with an <a id="I_indexterm15_id781449" class="indexterm"/><code class="literal">HttpConstraint</code> annotation element as follows:</p><a id="I_programlisting15_id781463"/><pre class="programlisting"><code class="nd">@ServletSecurity</code><code class="o">(</code> <code class="nd">@HttpConstraint</code><code class="o">(</code><code class="n">rolesAllowed</code> <code class="o">=</code> <code class="s">"secretagent"</code><code class="o">)</code> <code class="o">)</code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">SecureHelloClient</code> <code class="kd">extends</code> <code class="n">HttpServlet</code> <code class="o">{</code> <code class="o">...</code></pre><p>You can add this annotation to our test servlet or add the XML example setup to the <span class="emphasis"><em>web.xml</em></span> file for the <span class="emphasis"><em>learningjava.war</em></span> file and prepare to try it out. However, there is one additional step that you’ll have to take to get this working: create the user role “secretagent” and an actual user with this role in our application server environment.</p><p>Access to protected areas is granted to user roles, not individual users. A user role is effectively just a group of users; instead of granting access to individual users by name, you grant access to roles, and users are assigned one or more roles. A user role is an abstraction from users. Actual user information (name and password, etc.) is handled outside the sc