Wednesday, November 4, 2009

B.3 Web Application Structure




I l@ve RuBoard










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.)




  • Change directory into the webapps subdirectory
    of the Tomcat directory tree.


  • Create a directory in the webapps directory with
    the same name as the application (myapp), then
    change location into that directory.


  • In the myapp directory, create a directory named
    WEB-INF. The presence of this directory signals
    to Tomcat that myapp is an application context,
    so it must exist. Then restart Tomcat so it notices the new
    application.


  • Create a short test page named page1.html in the
    myapp directory that you can request from a
    browser to make sure that Tomcat is serving pages for the
    application. This is just a plain HTML file, to avoid complications
    that might arise from use of embedded Java, tag libraries, and so
    forth:

    <html>
    <head>
    <title>Test Page</title>
    </head>
    <body bgcolor="white">
    <p>
    This is a test.
    </p>
    </body>
    </html>

    To request the page, use a URL like this, adjusting it appropriately
    for your own server hostname and port number:


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



  • To try out a simple JSP page, make a copy of
    page1.html named page2.jsp.
    That creates a valid JSP page (even though it contains no executable
    code), so you should be able to request it and see output identical
    to that produced by page1.html:

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



  • Copy page2.jsp to page3.jsp
    and modify the latter to contain some embedded Java code by adding a
    couple of lines that print the current date and client IP number:

    <html>
    <head>
    <title>Test Page</title>
    </head>
    <body bgcolor="white">
    <p>
    This is a test.
    The current date is <%= new java.util.Date( ) %>.
    Your IP number is <%= request.getRemoteAddr ( ) %>.
    </p>
    </body>
    </html>

    The Date( ) method returns the current date, and
    getRemoteAddr( ) returns the client IP number from
    the object associated with the client request. After making the
    changes, request page3.jsp from your browser and
    the output should include the current date and the IP number of the
    host from which you requested the page.




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:



<?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/dtd/web-app_2_3.dtd">

<web-app>

</web-app>


Adding information to the web.xml file is a
matter of placing new elements between the
<web-app> and
</web-app> tags. As a simple illustration,
you can add a <welcome-file-list> 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:



<?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/dtd/web-app_2_3.dtd">

<web-app>
<welcome-file-list>
<welcome-file>page3.jsp</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>


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.









    I l@ve RuBoard



    No comments: