Search:
Locator+ Code:
FTP Home ? Javapro Home ? Archives ? Customer Service ? Site Map
Free Subscription to Java Pro
?
NEWER is BETTER


Explore the new Servlet 2.3 and JavaServer Pages 1.2
specifications and how they can help make programming easier


by Kevin Jones



he Servlet 2.3 and JavaServer Pages 1.2 specifications will soon be released. They contain many minor and several major changes to the previous specifications. This article will examine these changes and the reasoning behind them.

The major differences between the current Servlet 2.2 specification and the 2.3 proposed final draft (PFD) are the addition of filters and events to the servlet model. Filters provide a way for applications to provide standard actions both before and after the execution of any servlet. Events have long been missing from the servlet specification. An event provides notification of specific actions, notably application start/end and session start/end, allowing applications to perform one-off initialization.

Event Handlers
On many occasions, an application is required to perform some initialization as soon as it starts. For example, this can occur when creating and initializing JDBC connections or creating a JDBC connection pool, reading in resources that will be used throughout the application's lifetime, or simply checking that certain resources exist before the application can execute. An application that runs in a 2.2-compliant container has no guaranteed way of being able to perform this type of initialization.

In the 2.2 specification, a servlet can be deployed with a <load-on-startup> entry in the web.xml file. The element should contain a positive number. This is a hint to the container as to when the servlet should be loaded. The lower the number, the bigger the hint. This solution has a number of problems, however. First, the specification says the following: "The load-on-startup element indicates that this servlet should be loaded on the startup of the Web application." Container vendors could read this as "should be loaded, but don't have to be loaded" (so the servlet may not be loaded when the application starts). Another problem is that we are using a servlet in a way for which it is not really intended.

Servlets have "request" scope. That is, they are designed to be executed once per request from the client. In this case, we have a servlet that has "application" scope (it executes once and hangs around).

In the 2.2 specification, servlets can also be unloadeda container may look at the initialization servlet, decide it hasn't been used in a while, and unload it. If the servlet "owns" the resources it initialized at start-up, it should then free those resources.

Another problem is that a servlet won't be told when the application is ending. Its destroy method will get called at shutdown time, but there is no way for it to know if all the other servlets have also been unloaded. Other servlets may need to use the resources created by the initialization servlet when they are destroyed. If the initialization servlet is unloaded first, then the other servlets are out of luck.

The exact same issues arise with sessions. It is reasonable that an application does some initialization/tidy up for each session as it is created and destroyed.

To address these issues, the Servlet 2.3 specification introduces the concept of event handlers. Event handlers are code that can respond to specific events that are initiated by the container. In the Servlet 2.3 specification two types of events are defined: application events and session events. For both the event types, handlers can catch start and end events, and handlers can catch attribute change events.

We will concentrate on application start and end events but the code is very similar for the other event types.

Let's take a look at the event handler code. An application event handler has to extend javax.servlet.ServletContextListener. This interface has two methods,
contextDestroyed() and contextInitialized(), that both take a ServletContextEvent parameter. As you can imagine, the contextInitialized() method is called at application start time, and contextDestroyed() when the application ends. The ServletContextEvent class has a method that returns a reference to the ServletContext being created or destroyed.

As an example, imagine that you are building a simple Web-based white pages application where users can look up a name and phone number based on an e-mail (see Listing 1). In this example you will hold the white page entries in a hashtable. The hashtable needs to be created at application startup time and stored in the application's ServletContext.

The code is very straightforward. The class implements ServletContextListener. A constructor creates the hashtable. The contextDestroyed() method does nothing since the application is being unloaded anywaywe don't need to tidy up. The interesting work is in contextInitialized(). This method stores the data we need in the hashtable, then stores the hashtable in the ServletContext. When contextInitialized() is called, it is passed a reference to a ServletContextEvent object. The ServletContextEvent class has a single getServletContext() method that returns a reference to this application's ServletContext. Once that reference has been retrieved, the hashtable is stored.

An application has to be configured to use this event handler. This is done by amending the application's deployment descriptor (the web.xml file):

<web-app>
   <listener>
      <listener-class>
         WhitePagesListener
      </listener-class>
   </listener>
   ...

Any number of listeners can be configured in this way. Listeners are invoked in the order in which they appear in the deployment descriptor. Listeners are singletons, and the developer is responsible for synchronization. This isn't particularly important for ServletContextListeners but will be for all the other types.

?
Filters

In this Article
Introduction Request Dispatching
Filters More Updates