B.3. Web Application Structure

Each web application corresponds to a single servlet context and exists as a collection of resources. Some of these resources are visible to clients, while others are not. For example, an application's JSP pages may be available to clients, but the configuration, property, or class files that are used by the JSP pages can be hidden. The location of components within the application hierarchy determines whether or not clients can see them. This allows you to make resources public or private depending on where you put them.

Java Servlet Specification 2.3 defines the standard for web application layout. This helps application developers by providing conventions that indicate where to put what, along with rules that define which parts of the application the container will make available to clients and which parts are hidden.

Each web application corresponds to a single servlet context. In Tomcat, these are represented by directories under the webapps directory that serves as the "parent" of all web applications. Within an application directory, you'll find a WEB-INF subdirectory, and usually other files such as HTML pages, JSP pages, or image files. The files that are located in the application's top-level directory are public and may be requested by clients. The WEB-INF directory has special significance. Its mere presence signifies to Tomcat that its parent directory actually represents an application. WEB-INF is thus the only required component of a web application; it must exist, even if it's empty. If WEB-INF is nonempty, it typically contains application-specific configuration files, classes, and possibly other information. Three of its most common primary components are:

WEB-INF/web.xml

WEB-INF/classes

WEB-INF/lib

web.xml is the web application deployment descriptor file. It gives the container a standard way to discover how to handle the resources that make up the application. The deployment descriptor is often used for purposes such as defining the behavior of JSP pages and servlets, setting up access control for protected information, specifying error pages to be used when problems occur, and defining where to find tag libraries.

The classes and lib directories under WEB-INF hold class files and libraries, and sometimes other information. Individual class files go under classes, using a directory structure that corresponds to the class hierarchy. (For example, a class file MyClass.class that implements a class named com.kitebird.jsp.MyClass would be stored in the directory classes/com/kitebird/jsp.) Class libraries packaged as JAR files go in the lib directory instead. Tomcat looks in the classes and lib directories automatically when processing requests for pages from the application. This allows your pages to use application-specific information with a minimum of fuss.

The WEB-INF directory is also special in that it is private. Its contents are available to the application's servlets and JSP pages but cannot be accessed directly through a browser, so you can place information there that should not be displayed to clients. For example, you can store a properties file under WEB-INF that contains connection parameters for a database server. Or if you have an application that allows image files to be uploaded by one page and downloaded later by another page, putting the images into a directory under WEB-INF makes them private. Because Tomcat will not serve the contents of WEB-INF directly, your JSP pages can implement an access control policy that determines who can perform image operations. (A simple policy might require clients to specify a name and password before being allowed to upload images.) The WEB-INF directory is also beneficial in that it gives you a known location for private files that is fixed with respect to the application's root directory, no matter what machine you deploy the application on.

Clients that attempt to circumvent the private nature of the WEB-INF directory by issuing requests containing names such as Web-Inf in the path will find that its name is interpreted in case-sensitive fashion, even on systems with filenames that are not case sensitive, such as Windows or HFS+ filesystems under Mac OS X. Note that on such systems you should take care not to create the WEB-INF directory with a name like Web-Inf, web-inf, and so forth. The operating system itself may not consider the name any different than WEB-INF, but Tomcat will. The result is that none of the resources in the directory will be available to your JSP pages. Under Windows, it may be necessary to create a WEB-INF directory from the DOS prompt. (Windows Explorer may not respect the lettercase you use when creating or renaming a directory, just as it does not necessarily display directory names the same way the DIR command does from the DOS prompt.)

The preceding discussion describes web application layout in terms of a directory hierarchy, because that's the easiest way to explain it. However, an application need not necessarily exist that way. A web application typically is packaged as a WAR file, using the standard layout for components prescribed by the servlet specification. But some containers can run an application directly from its WAR file without unpacking it. Furthermore, a container that does unpack WAR files is free to do so into any filesystem structure it wishes.

Tomcat uses the simplest approach, which is to store an application in the filesystem using a directory structure that is the same as the directory tree from which the file was originally created. You can see this correspondence by comparing the structure of a WAR file to the directory hierarchy that Tomcat creates by unpacking it. For example, the WAR file for an application someapp can be examined using the this command:

% jar tf someapp.war

The list of pathnames displayed by the command corresponds to the layout of the someapp directory created by Tomcat when it unpacks the file under the webapps directory. To verify this, recursively list the contents of the someapp directory using one of these commands:

% ls -R someapp (Unix) C:> dir /s someapp (Windows)

If you were to set up a context manually for an application named myapp, the steps would be something like those shown in the following procedure. (If you want to see what the resulting application hierarchy should be, have a look at the tomcat/myapp directory of the recipes distribution.)

Test Page

This is a test.

Test Page

This is a test. The current date is <%= new java.util.Date( ) %>. Your IP number is <%= request.getRemoteAddr ( ) %>.

At this point, you have a simple application context that consists of three pages (one of which contains executable code) and an empty WEB-INF directory. For most applications, WEB-INF will contain a web.xml file that serves as the web application deployment descriptor file to tell Tomcat how the application is configured. If you look through web.xml files in other applications that you install under Tomcat, you'll find that they can be rather complex, but a minimal deployment descriptor file looks like this:

Adding information to the web.xml file is a matter of placing new elements between the and tags. As a simple illustration, you can add a element to specify a list of files that Tomcat should look for when clients send a request URL that ends with myapp and no specific page. Whichever file Tomcat finds first becomes the default page that is sent to the client. For example, to specify that Tomcat should consider page3.jsp and index.html to be valid default pages, create a web.xml file in the WEB-INF directory that looks like this:

page3.jsp index.html

Restart Tomcat so it reads the new application configuration information, then issue a request that specifies no explicit page:

http://tomcat.snake.net:8080/myapp/

The myapp directory contains a page named page3.jsp, which is listed as one of the default pages in the web.xml file, so Tomcat should execute page3.jsp and send the result to your browser.

Категории