JSP and Tomcat Primer - MySQL Cookbook (2007)

MySQL Cookbook (2007)

Appendix C. JSP and Tomcat Primer

This appendix describes some essential concepts of JavaServer Pages (JSP) programming, which is used earlier in this book beginning with Chapter 17. The necessary background is fairly extensive, which is why the material is presented here in a separate appendix rather than breaking up the flow of that chapter. The topics discussed here are:

§ A brief overview of servlet and JSP technologies

§ Setting up the Tomcat server

§ Tomcat’s directory structure

§ The layout of web applications

§ Elements of JSP pages

For pointers to additional information about JSP pages, servlets, or Tomcat, see Appendix D.

Servlet and JavaServer Pages Overview

Java servlet technology is a means by which to execute Java programs efficiently in a web environment. The Java Servlet Specification defines the conventions of this environment, which may be summarized briefly as follows:

§ Servlets run inside a servlet container, which itself either runs inside a web server or communicates with one. Servlet containers are also known as servlet engines.

§ The servlet container receives requests from the web server and executes the appropriate servlet to process the request. The container then receives the response from the servlet and gives it to the web server, which in turn returns it to the client. A servlet container thus provides the connection between servlets and the web server under which they run. The container acts as the servlet runtime environment, with responsibilities that include determining the mapping between client requests and the servlets that handle them, as well as loading, executing, and unloading servlets as necessary.

§ Servlets communicate with their container according to established conventions. Each servlet is expected to implement methods with well-known names to be called in response to various kinds of requests. For example, GET and POST requests are routed to methods named doGet() anddoPost().

§ Servlets that can be run by a container are arranged into logical groupings called “contexts.” (Contexts might correspond, for example, to subdirectories of the document tree that is managed by the container.) Contexts also can include resources other than servlets, such as HTML pages, images, or configuration files.

§ A context provides the basis for a “web application,” which the Java Servlet Specification defines as follows:

A Web application is a collection of servlets, HTML pages, classes, and other resources that make up a complete application on a Web server.

In other words, an application is a group of related servlets that work together, without interference from other unrelated servlets. Servlets within a given application context can share information with each other, but servlets in different contexts cannot. For example, a gateway or login servlet might establish a user’s credentials, which then are placed into the context environment to be shared with other servlets within the same context as proof that the user has logged in properly. Should those servlets find the proper credentials not to be present in the environment when they execute, they can redirect to the gateway servlet automatically to require the user to log in. Servlets in another context cannot gain access to these credentials. Contexts thus provide a measure of security by preventing one application from invading another. They also can insulate applications from the effects of another application crashing; the container can keep the noncrashed applications running while it restarts the one that failed.

§ Sharing of information between servlets may take place at several scope levels, which enables them to work together within the scope of a single request or across multiple requests.

The following listing shows what a simple servlet looks like. It’s a Java program that implements a SimpleServlet class. The class has a doGet() method to be invoked by the servlet container when it receives a get request for the servlet. It also has a doPost() method to handle the possibility that a post request may be received instead; it’s simply a wrapper that invokes doGet(). SimpleServlet produces a short HTML page that includes some static text that is the same each time the servlet runs, and two dynamic elements (the current date and client IP address) that vary over time and for each client:

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class SimpleServlet extends HttpServlet

{

public void doGet (HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException

{

PrintWriter out = response.getWriter ();

response.setContentType ("text/html");

out.println ("<html>");

out.println ("<head>");

out.println ("<title>Simple Servlet</title>");

out.println ("</head>");

out.println ("<body bgcolor=\"white\">");

out.println ("<p>Hello.</p>");

out.println ("<p>The current date is "

+ new Date ()

+ ".</p>");

out.println ("<p>Your IP address is "

+ request.getRemoteAddr ()

+ ".</p>");

out.println ("</body>");

out.println ("</html>");

}

public void doPost (HttpServletRequest request,

HttpServletResponse response)

throws IOException, ServletException

{

doGet (request, response);

}

}

As you will no doubt observe, this “simple” servlet really isn’t so simple! It requires a fair amount of machinery to import the requisite classes and to establish the doGet() and doPost() methods that provide the standard interface to the servlet container. Compare the servlet to the following PHP script, which does the same thing in a much more concise fashion:

<html>

<head>

<title>Simple PHP Page</title>

</head>

<body bgcolor="white">

<p>Hello.</p>

<p>The current date is <?php print (date ("D M d H:i:s T Y")); ?>.</p>

<p>Your IP address is <?php print ($_SERVER["REMOTE_ADDR"]); ?>.</p>

</body>

</html>

The contrast between the Java servlet and the PHP script illustrates one of the problems with writing servlets—the amount of repetitious overhead:

§ A certain minimal set of classes must be imported into each servlet.

§ The framework for setting up the servlet class and the doGet() or doPost() methods is fairly stereotypical, often varying among servlets only in the servlet class name.

§ Each fragment of HTML is produced with an output statement.

The first two points can be addressed by using a prototype file that you copy when beginning a new servlet. The third point (wrapping each line of HTML within a print statement) is not so easily addressed and is possibly the single most tedious aspect of servlet writing. It also leads to another issue: A servlet’s code may be easy enough to read as Java, but it’s sometimes difficult to discern the structure of the HTML that the code generates. The problem is that you’re really trying to write in two languages at once (that is, you’re writing Java that writes HTML), which isn’t really optimal for either language.

JSP Pages: An Alternative to Servlets

One of the reasons for the invention of JavaServer Pages was to relieve the burden involved in creating web pages with a lot of print statements. JSP uses a notational approach that is similar to PHP: Write the HTML literally and embed the code to be executed within special markers. The following listing shows a JSP page that is equivalent to the SimpleServlet servlet, but looks much more like the corresponding PHP script:

<html>

<head>

<title>Simple JSP Page</title>

</head>

<body bgcolor="white">

<p>Hello.</p>

<p>The current date is <%= new java.util.Date () %>.</p>

<p>Your IP address is <%= request.getRemoteAddr () %>.</p>

</body>

</html>

The JSP page is more concise than the servlet in several ways:

§ The standard set of classes required to run a servlet need not be imported. This is done automatically.

§ The HTML is written more naturally, without using print statements.

§ No class definition is required, nor any doGet() or doPost() methods.

§ The response and out objects need not be declared, because they’re set up for you and ready to use as implicit objects. In fact, the JSP page just shown doesn’t refer to out explicitly at all, because its output-producing constructs write to out automatically.

§ The default content type is text/html; there’s no need to specify it explicitly.

§ The script includes literal Java by placing it within special markers. The page just shown uses <%= and %>, which mean “evaluate the expression and display its result.” There are other markers as well, each of which has a specific purpose. (For a brief summary, see “Elements of JSP Pages” later in this appendix.)

When a servlet container receives a request for a JSP page, it treats the page as a template containing literal text plus executable code embedded within special markers. The container produces an output page from the template to send to the client. Literal text from the template is left unmodified, the executable code is replaced by any output that it generates, and the combined result is returned to the client as the response to the request. That’s the conceptual view of JSP processing, at least. When a container processes a JSP request, this is what really happens:

1. The container translates the JSP page into a servlet—that is, into an equivalent Java program. Instances of template text are converted to print statements that output the text literally. Instances of code are placed into the program so that they execute with the intended effect. This is all placed within a wrapper that provides a unique class name and that includes import statements to pull in the standard set of classes necessary for the servlet to run properly in a web environment.

2. The container compiles the servlet to produce an executable class file.

3. The container executes the class file to generate an output page, which is returned to the client as the response to the request.

4. The container also caches the executable class so that when the next request for the JSP page arrives, the container can execute the class directly and skip the translation and compilation phases. If the container notices that a JSP page has been modified the next time it is requested, it discards the cached class and recompiles the modified page into a new executable class.

Notationally, JSP pages provide a more natural way to write web pages than do servlets. Operationally, the JSP engine provides the benefits of automatic compilation after the page is installed in the document tree or modified thereafter. When you write a servlet, any changes require recompiling the servlet, unloading the old one, and loading the new one. That can lead to an emphasis on messing with the servlet itself rather than a focus on the servlet’s purpose. JSP reverses the emphasis so that you think more about what the page does than about the mechanics of getting it compiled and loaded properly.

The differences between servlets and JSP pages do not imply any necessity of choosing to use only one or the other. Application contexts in a servlet container can include both, and because JSP pages are converted into servlets anyway, they can all intercommunicate.

JSP is similar enough to certain other technologies that it can provide a migration path away from them. For example, the JSP approach is much like that used in Microsoft’s Active Server Pages (ASP). However, JSP is vendor- and platform-neutral, whereas ASP is proprietary. JSP thus provides an attractive alternative technology for anyone looking to move away from ASP.

Custom Actions and Tag Libraries

A servlet looks a lot like a Java program, because that’s what it is. The JSP approach encourages a cleaner separation of HTML (presentation) and code, because you need not generate HTML from within Java print statements. On the other hand, JSP doesn’t require separation of HTML and code, so it’s still possible to end up with lots of embedded Java in a page if you’re not careful.

One way to avoid inclusion of literal Java in JSP pages is to use another JSP feature known as custom actions. These take the form of special tags that look a lot like HTML tags (because they are written as XML elements). Custom actions enable tags to be defined that perform tasks on behalf of the page in which they occur. For example, a <sql:query> tag might communicate with a database server to issue a query. Custom actions typically come in groups, which are known as tag libraries and are designed as follows:

§ The actions performed by the tags are implemented by a set of classes. These are just regular Java classes, except that they are written according to a set of interface conventions that enable the servlet container to communicate with them in a standard way. (The conventions define how tag attributes and body content are passed to tag handler classes, for example.) Typically, the set of classes is packaged into a JAR file.

§ The library includes a tag library descriptor (TLD) file that specifies how each tag maps onto the corresponding class. This enables the JSP processor to determine which class to invoke for each custom tag that appears in a JSP page. The TLD file also indicates how each tag behaves, such as whether it has any required attributes. This information is used at page translation time to determine whether a JSP page uses the tags in the library correctly. For example, if a tag requires a particular attribute and the tag is used in a page without it, the JSP processor can detect that problem and issue an appropriate error message.

Tag libraries make it easier to write entire pages using tag notation rather than switching between tags and Java code. The notation is JSP-like, not Java-like, but the effect of placing a custom tag in a JSP page is like making a method call. This is because a tag reference in a JSP page maps onto a method invocation in the servlet that the page is translated into.

To illustrate the difference between the embedded-Java and tag library approaches, compare two JSP scripts that set up a connection to a MySQL server and display a list of tables in the cookbook database. The first one does so using Java embedded within the page:

<%@ page import="java.sql.*" %>

<html>

<head>

<title>Tables in cookbook Database</title>

</head>

<body bgcolor="white">

<p>Tables in cookbook database:</p>

<%

Connection conn = null;

String url = "jdbc:mysql://localhost/cookbook";

String user = "cbuser";

String password = "cbpass";

Class.forName ("com.mysql.jdbc.Driver").newInstance ();

conn = DriverManager.getConnection (url, user, password);

Statement s = conn.createStatement ();

s.executeQuery ("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"

+ " WHERE TABLE_SCHEMA = 'cookbook'"

+ " ORDER BY TABLE_NAME");

ResultSet rs = s.getResultSet ();

while (rs.next ())

out.println (rs.getString (1) + "<br />");

rs.close ();

s.close ();

conn.close ();

%>

</body>

</html>

The same thing can be done by using a tag library, such as the JSP Standard Tag Library (JSTL). JSTL consists of several tag sets grouped by function. Using its core and database tags, the preceding JSP page can be converted as follows to avoid entirely the use of literal Java:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<html>

<head>

<title>Tables in cookbook Database</title>

</head>

<body bgcolor="white">

<p>Tables in cookbook database:</p>

<sql:setDataSource

var="conn"

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost/cookbook"

user="cbuser"

password="cbpass"

/>

<sql:query dataSource="${conn}" var="rs">

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

WHERE TABLE_SCHEMA = 'cookbook'

ORDER BY TABLE_NAME

</sql:query>

<c:forEach items="${rs.rowsByIndex}" var="row">

<c:out value="${row[0]}"/><br />

</c:forEach>

</body>

</html>

The taglib directives identify the TLD files that the page uses and indicate that actions from the corresponding tag sets will be identified by prefixes of c and sql. (In effect, a prefix sets up a namespace for a set of tags.) The <sql:dataSource> tag sets up the parameters for connecting to the MySQL server, <sql:query> issues a query, <c:forEach> loops through the result, and <c:out> adds each table name in the result to the output page. (I’m glossing over details, of course. For more information about the JSTL tags, see Using Tomcat to Run Web Scripts.)

If it’s likely that you’d connect to the database server the same way from most JSP pages in your application context, a further simplification can be achieved by moving the <sql:dataSource> tag to an include file. If you name the file jstl-mcb-setup.inc and place it in the application’sWEB-INF directory, any page within the application context can set up the connection to the MySQL server by accessing the file with an include directive. (By convention, application contexts use their WEB-INF directory for private context-specific information. See the section “Web Application Structure.”) Modifying the preceding page to use the include file results in a script that looks like this:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

<%@ include file="/WEB-INF/jstl-mcb-setup.inc" %>

<html>

<head>

<title>Tables in cookbook Database</title>

</head>

<body bgcolor="white">

<p>Tables in cookbook database:</p>

<sql:query dataSource="${conn}" var="rs">

SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES

WHERE TABLE_SCHEMA = 'cookbook'

ORDER BY TABLE_NAME

</sql:query>

<c:forEach items="${rs.rowsByIndex}" var="row">

<c:out value="${row[0]}"/><br />

</c:forEach>

</body>

</html>

You’re still using Java when you use a tag library, because tag actions map onto Java class invocations. But the notation follows XML conventions, so it’s less like writing program code and more like writing HTML page elements. If your organization produces web content using a“separation of powers” workflow, custom actions enable elements of the page that are produced dynamically to be packaged in a way that is easier for designers and other non-programmers to deal with. They don’t have to develop or work directly with the classes that implement tag actions; that’s left to the programmers who write the classes that correspond to the tags.

Setting Up a Tomcat Server

The preceding discussion provides a brief introduction to servlets and JSP pages, but says nothing about how you actually use a server to run them. This section describes how to install Tomcat, a JSP-aware web server. Tomcat, like Apache, is a development effort of the Apache Software Foundation.

As described earlier, servlets execute inside a container, which is an engine that communicates with or plugs into a web server to handle requests for pages that are produced by executing servlets. Some servlet containers can operate in standalone fashion, such that they function both as container and web server. That is how Tomcat works. By installing it, you get a fully functioning server with servlet-processing capabilities. In fact, Tomcat is a reference implementation for both the servlet and JSP specifications, so it also acts as a JSP engine, providing JSP-to-servlet translation services. The servlet container part is named Catalina, and the JSP processor is named Jasper.

It’s possible to use the container part of Tomcat in conjunction with other web servers. For example, you can set up a cooperative arrangement between Apache and Tomcat under which Apache acts as a front end that passes servlet and JSP requests through to Tomcat and handles other requests itself. You can find information about setting up Apache and Tomcat to work together this way on the Tomcat web site.

To run a Tomcat server, you need three things:

A Java Software Development Kit (SDK)

This is required because Tomcat needs to compile Java servlets as part of its operation. You most likely already have an SDK installed if you’ve been compiling Java programs while reading earlier chapters. If you don’t have an SDK, see Appendix B for information on obtaining and installing one.

Tomcat itself

Tomcat is available from http://tomcat.apache.org. A fair amount of Tomcat documentation is available there, too. In particular, if you’re a newcomer to Tomcat, I recommend that you read the Introduction and the Application Developer’s Guide.

Some knowledge of XML

Tomcat configuration files are written as XML documents, and many scripting elements within JSP pages follow XML syntax rules. If you’re new to XML, the “XML and XHTML in a Nutshell” sidebar in Introduction describes some of its characteristics in comparison to HTML.

Installing a Tomcat Distribution

Currently, Tomcat is available in several versions (such as 4.1, 5.0, and 5.5). This section describes Tomcat 5.0. The instructions should also work for Tomcat 5.5, although you might need to upgrade your version of Java (Tomcat 5.5 requires JS2E 5.0).

To install Tomcat, get a binary distribution from tomcat.apache.org. (I assume that you don’t intend to build it from source, which is more difficult.) Tomcat distributions are available in several file formats, distinguished by filename extensions that have the following meanings:

.tar.gz

A compressed tar file, usually used for Unix installs

.zip

A ZIP archive, applicable to either Unix or Windows

.exe

An executable installer, used on Windows only

If you’re using Linux, the vendor of your Linux distribution might make Tomcat available on the distribution media or via an online APT or RPM repository. This method is not covered here in any depth. See your Linux distribution documentation or contact your vendor for details.

For a distribution packaged as a tar or ZIP file, you should place it in the directory under which you want to install Tomcat, and then run the installation command in that directory to unpack the distribution there. The Windows .exe installer prompts you to indicate where to install Tomcat, so it too can be run from any directory. The following commands are representative of those needed to install each distribution type. (Change the version numbers in the filenames to reflect the actual Tomcat distribution that you’re using.)

To install Tomcat from a compressed tar files, unpack it like this:

%tar zxf jakarta-tomcat-5.0.28.tar.gz

If you have trouble unpacking a Tomcat tar file distribution under Mac OS X, use gnutar rather than tar. On older versions of Mac OS X, tar has some problems with long filenames that gnutar does not. (In current versions, both programs are the same.) It may also be necessary to use a GNU-compatible version of tar under Solaris.

If your version of tar doesn’t understand the z option, do this instead:

%gunzip -c jakarta-tomcat-5.0.28.tar.gz | tar xf -

If you use a ZIP archive, you can unpack it with the jar utility or any other program that understands ZIP format (such as the Windows WinZip application). For example, to use jar, do this:

%jar xf jakarta-tomcat-5.0.28.zip

The Windows .exe distribution is directly executable. Launch it, and then indicate where you want to place Tomcat when the installer prompts for a location. If you use this installer, be sure that you already have a Java SDK installed first; the installer puts some files into the SDK hierarchy, an operation that fails if the SDK isn’t present. For versions of Windows that have service management (such as Windows NT, 2000, or XP), the .exe installer gives you the option of installing Tomcat as a service so that it starts automatically at system boot time.

Most of the installation methods create a directory and unpack Tomcat under it. The top-level directory of the resulting hierarchy is the Tomcat root directory. I’ll assume here that the Tomcat root is /usr/local/jakarta-tomcat under Unix. Under Windows, I'll assume C:\jakarta-tomcat. (The actual directory name likely will have a version number at the end.) The Tomcat root contains various text files containing information that is useful in the event that you have general or platform-specific problems. It also contains a number of directories. If you want to explore these now, see the section “Tomcat’s Directory Structure.” Otherwise, proceed to the next section, “Starting and Stopping Tomcat,” to find out how to run Tomcat.

Starting and Stopping Tomcat

Tomcat can be controlled manually, and also set to run automatically when your system starts up. It’s good to become familiar with the Tomcat startup and shutdown commands that apply to your platform, because you’ll probably find yourself needing to stop and restart Tomcat fairly often—at least while you’re setting it up initially. For example, if you modify Tomcat’s configuration files or install a new application, you must restart Tomcat to get it to notice the changes.

Before running Tomcat, you’ll need to set a couple of environment variables. Make sure JAVA_HOME is set to the pathname of your SDK so that Tomcat can find it. You might also need to set CATALINA_HOME to the pathname of the Tomcat root directory.

To start and stop Tomcat manually under Unix, change location into the bin directory under the Tomcat root. I find that it’s useful to make the shell scripts in that directory executable (this is a one-time operation):

% chmod +x *.sh

You can control Tomcat with the following two shell scripts:

%./startup.sh

% ./shutdown.sh

To run Tomcat automatically at system boot time, look for a startup script such as /etc/rc.local or /etc/rc.d/rc.local (the pathname depends on your operating system) and add a few lines to it:

export JAVA_HOME=/usr/local/java/jdk

export CATALINA_HOME=/usr/local/jakarta-tomcat

$CATALINA_HOME/bin/startup.sh &

These commands will run Tomcat as root, however. To run it under a different user account, change the last command to invoke Tomcat with su instead and specify the username:

su -c $CATALINA_HOME/bin/startup.shuser_name &

If you use su to specify a username, make sure that Tomcat’s directory tree is accessible to that user or you will have file permission problems when Tomcat tries to access files. One way to do this is to run the following command as root in the Tomcat root directory:

#chown -R

user_name

.

Linux users who install Tomcat from vendor-supplied package files may find that the installation creates a script named tomcat (or perhaps something like tomcat4 or tomcat5) in the /etc/rc.d/init.d directory that can be used manually or for automatic startup. To use the script manually, change location into that directory and use these commands:

%./tomcat start

% ./tomcat stop

For automatic startup, you must activate the script by running the following command as root:

#chkconfig --add tomcat

Linux package installation also might create a user account with a login name such as tomcat or tomcat5 that is intended to be used for running Tomcat.

For Windows users, the distribution includes a pair of batch files in the bin directory for controlling Tomcat manually:

C:\>startup.bat

C:\> shutdown.bat

If you elected to install Tomcat as a service for versions of Windows that have service management, such as Windows NT, 2000, or XP, you should control Tomcat using the services console. You can use this to start or stop Tomcat, or to set Tomcat to run automatically when Windows starts. (The service name is Apache Tomcat.)

To try Tomcat, start it using whatever instructions are applicable to your platform. Then request the default page using your browser. The URL will look something like this:

http://localhost:8080/

Adjust your hostname and port number appropriately. For example, Tomcat normally runs on port 8080 by default, but if you install from package files under Linux, Tomcat may use a port number of 8180. If your browser receives the page correctly, you should see the Tomcat logo and links to examples and documentation. It’s useful at this point to follow the examples link and try a few of the JSP pages there, to see whether they compile and execute properly.

If you find that, despite setting the JAVA_HOME variable, Tomcat can’t find your Java compiler, try setting your PATH environment variable to explicitly include the directory containing the compiler. Normally, this is the bin directory under your SDK installation. You probably already havePATH set to something already. If so, you’ll want to add the bin directory to the current PATH setting. (See Appendix B for information about setting your PATH value.)

Tomcat’s Directory Structure

For writing JSP pages, it’s not strictly necessary to be familiar with the hierarchy of Tomcat’s directory layout. But it certainly doesn’t hurt, so change location into the Tomcat root directory and have a look around. You’ll find a number of standard directories, which are described in the following discussion, grouped by function. Note that your installation layout may not be exactly as described here. Some distribution formats omit a few of the directories, and the logs and work directories might not be created until you’ve started Tomcat for the first time.

Application Directories

From the point of view of an application developer, the webapps directory is the most important part of Tomcat’s directory hierarchy. Each application context has its own directory, which is placed within the webapps directory under the Tomcat root.

Tomcat processes client requests by mapping them onto locations under the webapps directory. For a request that begins with the name of a directory located under webapps, Tomcat looks for the appropriate page within that directory. For example, Tomcat serves the following two requests using the index.html and test.jsp pages in the mcb directory:

http://localhost:8080/mcb/index.html

http://localhost:8080/mcb/test.jsp

For requests that don’t begin with the name of a webapps subdirectory, Tomcat serves them from a special subdirectory named ROOT, which provides the default application context.[23]For the following request, Tomcat serves the index.html page from the ROOT directory:

http://localhost:8080/index.html

Applications typically are packaged as web archive (WAR) files and Tomcat by default looks for WAR files that need to be unpacked when it starts up. Thus, to install an application, you generally copy its WAR file to the webapps directory, restart Tomcat, and let Tomcat unpack it. The layout of individual application directories is described later in the section “Web Application Structure.”

A web application is a group of related servlets that work together, without interference from other unrelated servlets. Essentially what this means for Tomcat is that an application is everything under a subdirectory of the webapps directory. Because contexts are kept separate by servlet containers like Tomcat, one practical implication of this structure is that scripts in one application directory can’t mess with anything in another application directory.

Configuration and Control Directories

Two directories contain configuration and control files. The bin directory contains control scripts for Tomcat startup and shutdown, and conf contains Tomcat’s configuration files, which are written as XML documents. Tomcat reads its configuration files only at startup time. If you modify any of them, you must restart Tomcat for your changes to take effect.

The most important configuration file is server.xml, which controls Tomcat’s overall behavior. Another file, web.xml, provides application configuration defaults. This file is used in conjunction with any web.xml file an application may have of its own. The tomcat-users.xml file defines credentials for users that have access to protected server functions, such as the Manager application that enables you to control applications from your browser. (See “Restarting Applications Without Restarting Tomcat,” later) This file can be superseded by other user information storage mechanisms. For example, you can store Tomcat user records in MySQL instead. For instructions, look in the tomcat directory of the recipes distribution.

Class Directories

Several Tomcat directories are used for class files and libraries. They differ in function according to whether you want to make classes visible to applications, to Tomcat, or to both:

shared

This directory has two subdirectories, classes and lib, for class files and libraries that are visible to applications but not to Tomcat.

common

This directory has two subdirectories, classes and lib, for class files and libraries that should be visible both to applications and to Tomcat.

server

This directory has two subdirectories, classes and lib, for class files and libraries that are visible to Tomcat but not to applications.

Operational Directories

If they weren’t set up as part of the Tomcat installation process, Tomcat creates two additional directories that serve operational purposes when you start it for the first time. Tomcat writes log files to the log directory and uses a work directory for temporary files.

The files in the logs directory can be useful for diagnosing problems. For example, if Tomcat has a problem starting properly, the reason usually will have been written into one of the logfiles.

When Tomcat translates a JSP page into a servlet and compiles it into an executable class file, it stores the resulting .java and .class files under the work directory. (When you first begin working with JSP pages, you may find it instructive to have a look under the work directory to compare your original JSP pages with the corresponding servlets that Tomcat produces.)


[23] The webapps/ROOT directory is distinct from the Tomcat root directory, which is the top-level directory of the Tomcat tree.

Restarting Applications Without Restarting Tomcat

If you modify a JSP page, Tomcat recompiles it automatically when the page is next requested. But if the page uses a JAR or class file under the application’s WEB-INF directory and you update one of them, Tomcat normally won’t notice the change until you restart it.

One way to avoid restarts for an application is to provide a <Context> element for the application in Tomcat’s server.xml file that specifies a reloadable attribute of true. That will cause Tomcat to look for changes not only in JSP pages that are requested directly, but also for changes in classes and libraries under the WEB-INF directory that the pages use. For example, to write such a <Context> element for an application named mcb, you could add a line like this to Tomcat’s server.xml file:

<Context path="/mcb" docBase="mcb" debug="0" reloadable="true"/>

The <Context> element attributes tell Tomcat four things:

path

Indicates the URL that maps to pages from the application context. The value is the part of the URL that follows the hostname and port number.

docBase

Indicates where the application context directory is located, relative to the webapps directory in the Tomcat tree.

debug

Sets the context debugging level. A value of zero disables debug output; higher numbers generate more output.

reloadable

Specifies Tomcat recompilation behavior when a client requests a JSP page located in the application context. By default, Tomcat recompiles a page only after noticing a modification to the page itself. Setting reloadable to true tells Tomcat to also check any classes or libraries stored under the application’s WEB-INF directory that the page uses.

After modifying server.xml to add the <Context> element, restart Tomcat to make the change take effect.

Having Tomcat check for class and library changes can be extremely useful during application development to avoid repeated restarts. However, as you might expect, automatic class checking adds a lot of processing overhead and incurs a significant performance penalty. It’s better used on development systems than on production systems.

Another way to get Tomcat to recognize application changes without restarting the entire server is to use the Manager application. This enables you to reload applications on request from a browser, without the overhead caused by enabling the reloadable attribute. The Manager application is invoked using the path /manager at the end of the URL by which you access your Tomcat server. The URL also includes the command that you want to execute. For example, the following request shows which contexts are running:

http://localhost:8080/manager/list

To shut down and reload the mcb application without restarting Tomcat, use a URL like this:

http://localhost:8080/manager/reload?path=/mcb

For more information on using the Manager application and what its allowable commands are, see the Manager App HOW-TO:

http://tomcat.apache.org/tomcat-5.0-doc/manager-howto.html

This document may also be available locally by following the documentation link on your Tomcat server’s home page. Note particularly the part that describes how to set up a Tomcat user with the manager role, because you’ll need to provide a name and password to gain access to the Manager application. By default, user records are defined in Tomcat’s tomcat-users.xml configuration file. The tomcat directory of the recipes distribution contains information on storing Tomcat user records in MySQL instead.

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, whereas 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 clients can see them. This enables you to make resources public or private depending on where you put them.

Java Servlet Specification 2.4 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 namedcom.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 enables your pages to use application-specific information with a minimum of fuss.

The WEB-INF directory 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-INFthat 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. 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 from 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 prompt in a console window. (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 command line in a console window.)

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

1. Change location into the webapps subdirectory of the Tomcat directory tree.

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

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

4. 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:

5. <html>

6. <head>

7. <title>Test Page</title>

8. </head>

9. <body bgcolor="white">

10.<p>

11.This is a test.

12.</p>

13.</body>

</html>

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

http://localhost:8080/myapp/page1.html

14.To try 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://localhost:8080/myapp/page2.jsp

15.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:

16.<html>

17.<head>

18.<title>Test Page</title>

19.</head>

20.<body bgcolor="white">

21.<p>

22.This is a test.

23.The current date is <%= new java.util.Date() %>.

24.Your IP number is <%= request.getRemoteAddr () %>.

25.</p>

26.</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"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

version="2.4">

</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"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee

http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"

version="2.4">

<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, and then issue a request that specifies no explicit page:

http://localhost: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.

Elements of JSP Pages

An earlier section of this appendix described some general characteristics of JSP pages. This section discusses in more detail the kinds of constructs you can use.

JSP pages are templates that contain static parts and dynamic parts:

§ Literal text in a JSP page that is not enclosed within special markers is static; it’s sent to the client without change. The JSP examples in this book produce HTML pages, so the static parts of JSP scripts are written in HTML. But you can also write pages that produce other forms of output, such as plain text, XML, or WML.

§ The nonstatic (dynamic) parts of JSP pages consist of code to be evaluated. You distinguish code from static text by enclosing it within special markers. Some markers indicate page-processing directives or scriptlets. A directive gives the JSP engine information about how to process the page, whereas a scriptlet is a mini-program that is evaluated and replaced by whatever output it produces. Other markers take the form of tags written as XML elements; they are associated with classes that act as tag handlers to perform the desired actions.

The following sections discuss the various types of dynamic elements that JSP pages can contain.

Scripting Elements

Several sets of scripting markers allow you to embed Java code or comments in a JSP page:

<% ... %>

The <% and %> markers indicate a scriptlet—that is, embedded Java code. The following scriptlet invokes print() to write a value to the output page:

<% out.print (1+2); %>

<%= ... %>

These markers indicate an expression to be evaluated. The result is added to the output page, which makes it easy to display values with no explicit print statement. For example, these two constructs both display the value 3, but the second is easier to write:

<% out.print (1+2); %>

<%= 1+2 %>

<%! ... %>

The <%! and %> markers allow class variables and methods to be declared.

<%-- ... --%>

Text within these markers is treated as a comment and ignored. JSP comments disappear entirely and do not appear in the output that is returned to the client. If you’re writing a JSP page that produces HTML and you want the comment to appear in the final output page, use an HTML comment instead:

<%-- this comment will not be part of the final output page --%>

<!-- this comment will be part of the final output page -->

When a JSP page is translated into a servlet, all scripting elements effectively become part of the same servlet. This means that a variable declared in one element can be used by other elements later in the page. It also means that if you declare a given variable in two elements, the resulting servlet is illegal and an error will occur.

The <% ... %> and <%! ... %> markers both can be used to declare variables, but differ in their effect. A variable declared within <% ... %> is an object (or instance) variable; it is initialized each time that the page is requested. A variable declared within <%! ... %> is a class variable, initialized only at the beginning the life of the page. Consider the following JSP page, counter.jsp, which declares counter1 as an object variable and counter2 as a class variable:

<%-- counter.jsp - demonstrate object and class variable counters --%>

<% int counter1 = 0; %> <%-- object variable --%>

<%! int counter2 = 0; %> <%-- class variable --%>

<% counter1 = counter1 + 1; %>

<% counter2 = counter2 + 1; %>

<p>Counter 1 is <%= counter1 %></p>

<p>Counter 2 is <%= counter2 %></p>

If you install the page and request it several times, the value of counter1 will be 1 for every request. The value of counter2 increments across successive requests (even if different clients request the page), until Tomcat is restarted.

In addition to variables that you declare yourself, JSP pages have access to a number of objects that are declared for you implicitly. These are discussed in the later section, “Implicit JSP Objects.”

JSP Directives

The <%@ and %> markers indicate a JSP directive that provides the JSP processor with information about the kind of output the page produces, the classes or tag libraries it requires, and so forth.

<%@page ... %>

page directives provide several kinds of information, which are indicated by one or more attribute="value" pairs following the page keyword. The following directive specifies that the page scripting language is Java and that it produces an output page with a content type oftext/html:

<%@ page language="java" contentType="text/html" %>

This particular directive need not actually be specified at all, because java and text/html are the default values for their respective attributes.

If a JSP page produces non-HTML output, be sure to override the default content type. For example, if a page produces plain text, use this directive:

<%@ page contentType="text/plain" %>

An import attribute causes Java classes to be imported. In a regular Java program, you would do this using an import statement. In a JSP page, use a page directive instead:

<%@ page import="java.util.Date" %>

<p>The date is <%= new Date () %>.</p>

If you refer to a particular class only once, it may be more convenient to omit the directive and just refer to the class by its full name when you use it:

<p>The date is <%= new java.util.Date () %>.</p>

<%@include ... %>

The include directive inserts the contents of a file into the page translation process. That is, the directive is replaced by the contents of the included file, which is then translated itself. The following directive causes inclusion of a file named my-setup-stuff.inc from the application’s WEB-INF directory:

<%@ include file="/WEB-INF/my-setup-stuff.inc" %>

A leading / indicates a filename relative to the application directory (a context-relative path). No leading / means the file is relative to the location of the page containing the include directive.

Include files allow content (either static or dynamic) to be shared easily among a set of JSP pages. For example, you can use them to provide standard headers or footers for a set of JSP pages, or to execute code for common operations such as setting up a connection to a database server.

<%@taglib ... %>

A taglib directive indicates that the page uses custom actions from a given tag library. The directive includes attributes that tell the JSP engine how to locate the TLD file for the library and also the name you’ll use in the rest of the page to signify tags from the library. For example, a page that uses the core and database-access tags from JSTL might include the following taglib directives:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>

The uri (Uniform Resource Identifier) attribute uniquely identifies the tag library so that the JSP engine can find its TLD file. The TLD defines the behavior (the interface) of the actions so that the JSP processor can make sure the page uses the library’s tags correctly. A common convention for constructing unique uri values is to use a string that includes the host from which the tag library originates. That makes the uri value look like a URL, but it’s just an identifier; it doesn’t mean that the JSP engine actually goes to that host to fetch the descriptor file. The rules for interpreting the uri value are described in the later section “Using a Tag Library.”

The prefix attribute indicates how tags from the library will be invoked. The directives just shown indicate that core and database tags will have the forms <c: xxx > and <sql: xxx >. For example, you can use the out tag from the core library as follows to display a value:

<c:out value="Hello, world."/>

Or you might issue a query with the database query tag like this:

<sql:query dataSource="${conn}" var="result">

SELECT id, name FROM profile ORDER BY id

</sql:query>

Action Elements

Action element tags can refer to standard (predefined) JSP actions, or to custom actions in a tag library. Tag names include a prefix and a specific action:

§ Tag names with a jsp prefix indicate predefined action elements. For example, <jsp:forward> forwards the current request to another page. This action is available to any page run under a standard JSP processor.

§ Custom actions are implemented by tag libraries. The prefix of the tag name must match the prefix attribute of a taglib directive that appears earlier in the page, so that the JSP processor can determine which library the tag is part of. To use custom tags, the library must be installed first. See “Using a Tag Library,” next.

Actions are written as XML elements within a JSP page, and their syntax follows normal XML rules. An element with a body is written with separate opening and closing tags:

<c:if test="${x == 0}">

x is zero

</c:if>

If the tag has no body, the opening and closing tags can be combined:

<jsp:forward page="some_other_page.jsp"/>

Using a Tag Library

Suppose that you have a tag library consisting of a JAR file mytags.jar and a tag library descriptor file mytags.tld. To make the library available to the JSP pages in a given application, both files must be installed. Typically, you put the JAR file in the application’s WEB-INF/lib directory and the TLD file in the WEB-INF directory.

A JSP page that uses the tag library must include an appropriate taglib directive before using any of the actions that the library provides:

<%@ taglib uri="tld-location" prefix="taglib-identifier" %>

The prefix attribute tells Tomcat how you’ll refer to tags from the library in the rest of the JSP page. If you use a prefix value of mytags, you can refer to tags later in the page like this:

<mytags:sometag attr1="attribute value 1" attr2="attribute value 2">

tag body

</mytags:sometag>

The prefix value is a name of your own choosing, but you must use it consistently throughout the page, and you cannot use the same value for two different tag libraries.

The uri attribute tells the JSP processor how to find the tag library’s TLD file. The value can be either direct or indirect:

§ You can specify the uri value directly as the pathname to the TLD file, which typically will be installed in the WEB-INF directory:

<%@ taglib uri="/WEB-INF/mytags.tld" prefix="mytags" %>

A leading / indicates a filename relative to the application directory (a context-relative path). No leading / means the file is relative to the location of the page containing the taglib directive.

If an application uses lots of tag libraries, a common convention for keeping TLD files from cluttering up the WEB-INF directory is to put them in a tld subdirectory of the WEB-INF directory. In that case, the uri value would be written like this instead:

<%@ taglib uri="/WEB-INF/tld/mytags.tld" prefix="mytags" %>

The disadvantage of specifying a TLD file pathname directly is that if a new version of the tag library is released and the TLD file has a different name, you’ll need to modify the taglib directive in every JSP page that refers to the file.

§ Another way to specify the location of the TLD file is by using the pathname to the tag library JAR file:

<%@ taglib uri="/WEB-INF/lib/mytags.jar" prefix="mytags" %>

The JSP processor can find the TLD file this way, provided a copy of it is included in the JAR file as META-INF/taglib.tld. However, this method suffers the same problem as specifying the TLD filename directly—if a new version of the library comes out with a different JAR file pathname, you must update taglib directives in individual JSP pages. It also doesn’t work for containers that can’t find TLD files in JAR files. (Older versions of Tomcat have this problem, for example.)

§ A third way to specify the location of the TLD file is to do so indirectly. Assign a symbolic name to the library and add a <taglib> entry to the application’s web.xml file that maps the symbolic name to the pathname of the TLD file. Then refer to the symbolic name in your JSP pages. Suppose that you define the symbolic name for the mytags tag library as:

http://terrific-tags.com/mytags

The <taglib> entry in web.xml should list the symbolic name and provide the path to the corresponding TLD file. If the file is installed in the WEB-INF directory, write the entry like this:

<taglib>

<taglib-uri>http://terrific-tags.com/mytags</taglib-uri>

<taglib-location>/WEB-INF/mytags.tld</taglib-location>

</taglib>

If the file is installed in WEB-INF/tld instead, write the entry like this:

<taglib>

<taglib-uri>http://terrific-tags.com/mytags</taglib-uri>

<taglib-location>/WEB-INF/tld/mytags.tld</taglib-location>

</taglib>

Either way, you refer to the tag library in JSP pages using the symbolic name, like this:

<%@ taglib uri="http://terrific-tags.com/mytags" prefix="mytags" %>

Using a symbolic TLD name involves a level of indirection, but has a significant advantage in that it provides a more stable means by which to refer to the tag library in JSP pages. You specify the actual location of the TLD file only in web.xml, rather than in individual JSP pages. If a new version of the tag library comes out and the TLD file has a different name, just change the <taglib-location> value in web.xml and restart Tomcat to enable your JSP pages to use the new library. There’s no need to change any of the JSP pages that use the tags.

Implicit JSP Objects

When a servlet runs, the servlet container passes it two arguments representing the request and the response, but you must declare other objects yourself. For example, you can use the response argument to obtain an output-writing object like this:

PrintWriter out = response.getWriter ();

A convenience that JSP provides in comparison to servlet writing is a set of implicit objects—that is, standard objects that are provided as part of the JSP execution environment. You can refer to any of these objects without explicitly declaring them. Thus, in a JSP page, the out object can be treated as having already been set up and made available for use. Some of the more useful implicit objects are:

pageContext

An object that provides the environment for the page.

request

An object that contains information about the request received from the client, such as the parameters submitted in a form.

response

The response being constructed for transmission to the client. You can use it to specify response headers, for example.

out

The output object. Writing to this object via methods such as print() or println() adds text to the response page.

session

Tomcat provides access to a session that can be used to carry information from request to request. This enables you to write applications that interact with the user in what seems to be a cohesive series of events. Sessions are described more fully in Chapter 20.

application

This object provides access to information that is shared on an application-wide basis.

Levels of Scope in JSP Pages

JSP pages have access to several scope levels, which can be used to store information that varies in how widely available it is. The scope levels are:

Page scope

Information that is available only to the current JSP page.

Request scope

Information that is available to any of the JSP pages or servlets that are servicing the current client request. It’s possible for one page to invoke another during request processing; placing information in request scope enables such pages to communicate with each other.

Session scope

Information that is available to any page servicing a request that is part of a given session. Session scope can span multiple requests from a given client.

Application scope

Information that is available to any page that is part of the application context. Application scope can span multiple requests, sessions, or clients.

One context knows nothing about other contexts, but pages served from within the same context can share information with each other by registering attributes (objects) in one of the scopes that are higher than page scope.

To move information into or out of a given scope, use the setAttribute() or getAttribute() methods of the implicit object corresponding to that scope (pageContext, request, session, or application). For example, to place a string value tomcat.example.com into request scope as an attribute named myhost, use the request object:

request.setAttribute ("myhost", "tomcat.example.com");

setAttribute() stores the value as an Object. To retrieve the value later, fetch it by name using getAttribute() and then coerce it back to string form:

Object obj;

String host;

obj = request.getAttribute ("myhost");

host = obj.toString ();

When used with the pageContext object, setAttribute() and getAttribute() default to page context. Alternatively, they can be invoked with an additional parameter of PAGE_SCOPE, REQUEST_SCOPE, SESSION_SCOPE, or APPLICATION_SCOPE to specify a scope level explicitly. The following statements have the same effect as those just shown:

pageContext.setAttribute ("myhost", "tomcat.example.com",

pageContext.REQUEST_SCOPE);

obj = pageContext.getAttribute ("myhost", pageContext.REQUEST_SCOPE);

host = obj.toString ();