View RSS Feed

Servlet

General Event Handling in Servlets Part 1

Rate this Entry
by , 11-28-2011 at 11:15 PM (2396 Views)
When you are developing applications using servlets or JSP pages, there are a number of tools at your disposal for handling the life cycle of individual servlets or JSP pages. The servlet init method fires when a servlet is first instantiated. With JSP pages it is the jspInit method. Both methods can use initialization parameters that are specified with the init-param subelement of the web.xml servlet element. Requests are handled with service and _jspService, and destruction is handled with destroy and jspDestroy.

This is all well and good for individual resources. Now if you want to respond to major events in the life cycle of the Web application itself, there is no good answer to this question. It is impossible to know which resources will be accessed first so you end up repeating the same code in numerous places to performs these tasks. If you want to have more global control than any one servlet or JSP page can provide then you need to think about using application life-cycle event listeners.

There are eight kinds of event listeners that respond to Web application life-cycle events:
  • Servlet context listeners - These listeners are notified when the servlet context (i.e., the Web application) is initialized and destroyed.
  • Servlet context attribute listeners - These listeners are notified when attributes are added to, removed from, or replaced in the servlet context.
  • Session listeners - These listeners are notified when session objects are created, invalidated, or timed out.
  • Session attribute listeners - These listeners are notified when attributes are added to, removed from, or replaced in any session.
  • Session migration listeners - These listeners are notified when the session objects are serialized and deserialized by the container. Usually, the serialization and deserialization of session objects occurs when the container migrates the session objects from one machine to another.
  • Session object binding listeners - These listeners are notified when the implementing object is added or removed from the session object.
  • Request listeners - These listeners are notified when request objects are initialized and destroyed.
  • Request attribute listeners - These listeners are notified when attributes are added to, removed from, or replaced in any request.


The steps for using these listeners is straightforward, they are:
  • Implement the appropriate interface. Use ServletContextListener, ServletContextAttributeListener, HttpSessionListener, HttpSessionAttributeListener, HttpSessionActivationListener, HttpSessionBindingListener, ServletRequestListener, or ServletRequestAttributeListener. The interfaces without the Http prefix in their name reside in the javax.servlet package and the interfaces with the Http prefix reside in the javax.servlet.http package.
  • Implement the methods needed to respond to the events of interest. Provide empty bodies for the other methods in the interface. For example, the ServletContextListener interface defines two methods: contextInitialized (the Web application was just loaded and the servlet context was initialized) and contextDestroyed (the Web application is being shut down and the servlet context is about to be destroyed). If you wanted to define an application-wide servlet context entry, you could provide a real implementation for contextInitialized and an empty body for contextDestroyed.
  • Obtain access to the important Web application objects. There are nine important objects that you are likely to use in your eventhandling methods: the servlet context, the name of the servlet context attribute that changed, the value of the servlet context attribute that changed, the session object, the name of the session attribute that changed, the value of the session attribute that changed, the request object, the name of the request attribute that changed, and the value of the request attribute that changed.
  • Use these objects. This process is application specific, but there are some common themes. For example, with the servlet context, you are most likely to read initialization parameters (getInitParameter), store data for later access (setAttribute), and read previously stored data (getAttribute).
  • Declare the listener. You do this with the listener and listener-class elements of the general Web application deployment descriptor (web.xml) or of a TLD file.
  • Provide any needed initialization parameters. Servlet context listeners commonly read context initialization parameters to use as the basis of data that is made available to all servlets and JSP pages. You use the context-param web.xml element to provide the names and values of these initialization parameters.


Note, that the ServletRequestListener and the ServletRequestAttributeListener are new additions from version 2.4 of the servlet specification. If your Web application needs to support servers compliant only with version 2.3, avoid using these listeners.

Letís now look into the look at the first of the listeners mentioned, The ServletContextListener that is used for monitoring the creation and destruction of the servlet context.

The ServletContextListener class responds to the initialization and destruction of the servlet context. These events correspond to the creation and shutdown of the Web application itself. The ServletContextListener is most commonly used to set up application-wide resources like database connection pools and to read the initial values of application-wide data that will be used by multiple servlets and JSP pages. Using the listener involves six steps.
  1. Implement the ServletContextListener interface. This interface is in the javax.servlet package.
  2. Implement contextInitialized and contextDestroyed. The first of these (contextInitialized) is triggered when the Web application is first loaded and the servlet context is created. The two most common tasks performed by this method are creating application-wide data (often by reading context initialization parameters) and storing that data in an easily accessible location (often in attributes of the servlet context). The second method (contextDestroyed) is triggered when the Web application is being shut down and the servlet context is about to be destroyed. The most common task performed by this method is the releasing of resources. For example, contextDestroyed can be used to close database connections associated with a now-obsolete connection pool. However, because the servlet context will be destroyed (and garbage collected if the server itself continues to execute), there is no need to use contextDestroyed to remove normal objects from servlet context attributes.
  3. Obtain a reference to the servlet context. ThecontextInitialized and contextDestroyed methods each take a ServletContextEvent as an argument. The ServletContextEvent class has a getServletContext method that returns the servlet context.
  4. Use the servlet context. You read initialization parameters with getInitParameter, store data with setAttribute, and make log file entries with log.
  5. Declare the listener. Use the listener and listener-class elements to simply list the fully qualified name of the listener class, as shown here:

<listener> 
 <listener-class>somePackage.SomeListener</listener-class>
</listener>

For now, assume that this declaration goes in the web.xml file. However, keep in mind that if you package listeners with tag libraries, you can use the identical declaration within the TLD file of the tag library.
  6. Provide any needed initialization parameters. Once you have a reference to the servlet context (see Step 3), you can use the getInitParameter method to read context initialization parameters as the basis of data that will be made available to all servlets and JSP pages. You use the context-param web.xml element to provide the names and values of these initialization parameters, as follows:
    


    Java Code:
    <context-param> 
    
          <param-name>name</param-name> 
    
          <param-value>value</param-value>

       </context-param>



To get a better sense of how this would work, Iíve put together an example based on mergers and acquisitions example based on one company purchasing another. In fact, that it is constantly being bought out by larger companies. As a result, the company name keeps changing. Rather than changing zillions of separate servlets and JSP pages each time you change the company name, you could read the company name when the Web application is loaded, store the value in the servlet context, and design all your servlets and JSP pages to read the name from this location. To prevent confusion among customers, the site can also prominently display the former company name, initializing and using it in a manner similar to the current company name.
The following steps summarize a listener that accomplishes this task.
  1. Implement the ServletContextListener interface. Listing 6.1 shows a class (InitialCompanyNameListener) that implements this interface.
  2. Implement contextInitialized and contextDestroyed. The InitialCompanyNameListener class uses context- Initialized to read the current and former company names and store them in the servlet context. Because the contextDestroyed method is not needed, an empty body is supplied.
  3. Obtain a reference to the servlet context. The context- Initialized method calls getServletContext on the ServletContextEvent argument and stores the result in the context local variable.
  4. Use the servlet context. The listener needs to store the company- Name and formerCompanyName initialization parameters in a globally accessible location, so it calls getInitParameter on the context variable, checks for missing values, and uses setAttribute to store the result in the servlet context.
  5. Declare the listener. The listener is declared in the deployment descriptor with the listener and listener-class elements, as shown here:

    Java Code:
       <listener> 
    
          <listener-class>coreservlets.listeners.InitialCompanyNameListener</listener-class>

       </listener>

    The listener code from the web.xml is shown in Listing 3.
  6. Provide any needed initialization parameters. The company-Name and formerCompanyName init parameters are defined in web.xml as follows:
    Java Code:
    <context-param> 
    
          <param-name>companyName</param-name> 
    
          <param-value>not-dot-com.com</param-value>

       </context-param> 
       
<context-param>
    
          <param-name>formerCompanyName</param-name>
    
          <param-value>hot-dot-com.com</param-value> 

       </context-param>


Listings 3 and 4 present two JSP pages that use the predefined JSP EL variable applicationScope (i.e., the servlet context) to access the companyName and formerCompanyName attributes. Figures 6Ė1 and 6Ė2 show the results.

Listing 1
Java Code:
package con.acme.webexample;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class InitialCompanyNameListener implements ServletContextListener {
	private static final String DEFAULT_NAME = "ACME";

	/**
	 * Looks up the companyName and formerCompanyName 
	 * init parameters and puts
	 * them into the servlet context.
	 */
	public void contextInitialized(ServletContextEvent event) {
		ServletContext context = event.getServletContext();
		setInitialAttribute(context, "companyName", DEFAULT_NAME);
		setInitialAttribute(context, "formerCompanyName", "");
	}

	public void contextDestroyed(ServletContextEvent event) {
	}

	// Looks for a servlet context init parameter with a // given name. If it
	// finds it, it puts the value into // a servlet context attribute with the
	// same name. If // the init parameter is missing, it puts a default //
	// value into the servlet context attribute.
	private void setInitialAttribute(ServletContext context,
			String initParamName, String defaultValue) {
		String initialValue = context.getInitParameter(initParamName);
		if (initialValue != null) {
			context.setAttribute(initParamName, initialValue);
		} else {
			context.setAttribute(initParamName, defaultValue);
		}
	}
}
Listing 2
Java Code:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	
	<display-name></display-name>
	<!-- Because the company name changes so frequently, supply it as a servlet 
		context parameter instead of embedding it into lots of different servlets 
		and JSP pages. The InitialCompanyNameListener will read this value and store 
		it in the servlet context. -->
	<context-param>
		<param-name>companyName</param-name>
		<param-value>acme.com</param-value>
	</context-param>
	<!-- Also store the previous company name. -->
	<context-param>
		<param-name>formerCompanyName</param-name>
		<param-value>nuts-and-bolts.com</param-value>
	</context-param>
	<!-- Register the listener that sets up the initial company name. -->
	<listener>
	    <listener-class>
		coreservlets.listeners.InitialCompanyNameListener
	    </listener-class>
	</listener>
	<!-- If URL gives a directory but no file name, try index.jsp first and 
		index.html second. If neither is found, the result is server specific (e.g., 
		a directory listing). Order of elements in web.xml matters. welcome-file-list 
		needs to come after servlet but before error-page. -->
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list> <!-- ... -->
</web-app>
Listing 3
XML Code:
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<head>
	<base href="<%=basePath%>">

	<title>${applicationScope.companyName}</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<link rel="stylesheet" type="text/css" href="events-styles.css">
</head>

<body>
	<table border=5 align="center">
		<tr>
			<th class="title">
				${applicationScope.companyName}
				<br>
				(formerly ${applicationScope.formerCompanyName})
	</table>
	<p>
		Welcome to the home page of
		<b> ${applicationScope.companyName}</b> (formerly
		${applicationScope.formerCompanyName})
	<p>
		<b>${applicationScope.companyName}</b> is a high-flying, fast-growing,
		big-potential company. A perfect choice for your retirement portfolio!

	
	<p>
		Click
		<a href="company-info.jsp">here</a> for more information.
</body>

Submit "General Event Handling in Servlets Part 1" to Facebook Submit "General Event Handling in Servlets Part 1" to Digg Submit "General Event Handling in Servlets Part 1" to del.icio.us Submit "General Event Handling in Servlets Part 1" to StumbleUpon Submit "General Event Handling in Servlets Part 1" to Google

Updated 11-30-2011 at 02:15 PM by Servlet

Categories
Tutorial , Web , Listener , ServletContextListener

Comments