Request ListenersS2C Home « Request Listeners

In the second of three lessons on listeners we make a thorough investigation of request listeners, which allow us to be alerted by request state alterations; whether it be when the lifecycle of the request scope has changed, or one of the attributes within the request scope has been added, removed or replaced.

Knowing when your request is about to come into scope can enhance pre-initialisation of request scoped resources; knowing when your request is about to go out of scope is useful if you have request attributes you want to save to another scope or for tidying up resources. It could also help with keeping track of resources or logging them to know when attributes are added, removed or replaced.

There are two request listener types we can use, these being javax.servlet.ServletRequestListener and javax.servlet.ServleRequestAttributeListener. When implemented, these types will trigger from the javax.servlet.ServletRequestEvent and javax.servlet.ServletRequestAttributeEvent event types respectively.

The request listeners and their related event types are summarized in the table below, use the links in the table to go to more detailed explanations of each interface and event type.

Listener Interface Event Type Description
ServletRequestListenerServletRequestEventYou want to know when a request, has come into, or gone out of, scope within the web application.
ServletRequestAttributeListenerServletRequestAttributeEventYou want to know when a request attribute has been added, replaced or removed within the servlet request.

We look at each request listener and request event type in more detail in the following sections and finish our discussion of request listeners with some code to see the various components in action.

The ServletRequestListener Interfacego to top of page Top

We implement the ServletRequestListener type when we want to receive notifications about changes to the request scope within the web application. This allows users of the interface to know when a request scope is about to be initialized or destroyed. This type of notification can be useful for any pre-initialization we need to do in the first instance and for any housekeeping, or storing of request attributes in another scope, in the second.

The two methods within the ServletRequestListener interface are shown in the table below. Click the links in the table below to go to code examples of the implemented methods.

Method Declaration Description
void requestInitialized(ServletRequestEvent sre)Receive notification that the request is about to come into scope within the web application.
void requestDestroyed(ServletRequestEvent sre)Receive notification that the request is about to go out of scope within the web application.

The ServletRequestEvent Classgo to top of page Top

ServletContextEvent is the event class for notifications about changes to request scope within the web application and consists of two methods which are used to return the ServletContext of this web application or the ServletRequest object for the event that fired. This class is also the parameter input for both of the ServletRequestListener methods we need to implement and is how we are alerted to changes when the event is triggered.

The two methods within the ServletRequestEvent class are shown in the table below. Click a link in the table below to go to code examples of the implemented methods.

Method Declaration Description
ServletContext getServletContext()Return the ServletContext of this web application.
ServletRequest getServletRequest()Return the ServletRequest that is changing.

The ServletRequestAttributeListener Interfacego to top of page Top

We implement the ServletRequestAttributeListener type when we want to receive notifications about changes to the attribute list of the servlet request within a web application. This allows users of the interface to know when an attribute has been added, removed or replaced. This type of notification can be useful for logging, messaging and housekeeping.

The three methods within the ServletRequestAttributeListener interface are shown in the table below. Click the links in the table below to go to code examples of the implemented methods.

Method Declaration Description
void attributeAdded(ServletRequestAttributeEvent srae)Receive notification that a new attribute has been added to the servlet request.
void attributeRemoved(ServletRequestAttributeEvent srae)Receive notification that an existing attribute has been removed from the servlet request.
void attributeReplaced(ServletRequestAttributeEvent srae)Receive notification that an existing attribute has been replaced within the servlet request.

The ServletRequestAttributeEvent Classgo to top of page Top

ServletRequestAttributeEvent is the event class for notifications about changes to the attribute list of the servlet request of this web application and consists of two methods which show the key/value pairing of the attribute in question. This class is also the parameter input for all of the ServletRequestAttributeListener methods we need to implement and is how we are alerted to changes when the event is triggered.

The two methods within the ServletRequestAttributeEvent class are shown in the table below. Click a link in the table below to go to a code example of the method.

Method Declaration Description
java.lang.String getName()Return the name of the attribute that has changed on ServletRequest.
java.lang.Object getValue()Returns the value of the attribute that was added, removed, or replaced.

If the attribute was added, this is the value of the added attribute.
If the attribute was removed, this is the value of the removed attribute.
If the attribute was replaced, this is the old value of the attribute.

Example Of Request Listenersgo to top of page Top

We will keep it simple so you can see how the ServletRequestListener and ServletRequestAttributeListener listeners are implemented and what else we need to do to get our listeners working. It is not an intention of this tutorial to go into details about event handling, although if you are interested it works in the same way as Swing for example. For more details on event handling you can find information on my Java6 Tutor site at Swing - Event Handling.

Within the _ServletsAdv folder create a new folder for this lesson called requestlisteners

Within the requestlisteners folder we will create separate folders to hold our DD, source files and our compiled byte code and these will be called dd, src and classes.

Within the src folder create a subfolders called controller.

So after creating these folders your directory structure should look something like the following screenshot:

requestlisteners directory structure

Coding The Listenersgo to top of page Top

We are now ready to code our listeners which will consist of implementations of the ServletContextListener, ServletRequestListener and ServletRequestAttributeListener interfaces.

Coding ImplServletContextListener

The ImplServletContextListener class implements the contextInitialized() and contextDestroyed() methods of the ServletContextListener interface. Within the overridden contextInitialized() method we output a message to the console, extract the context initialisation parameter from the DD and create a 'counter' context attribute we will be using within request scope.

Cut and paste the following code into your text editor and save in the   c:\_ServletsAdv\requestlisteners\src\controller directory as ImplServletContextListener.java.


package controller;
import javax.servlet.*;

public class ImplServletContextListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent event) { 
        // Write to console
        System.out.println("Within the contextInitialized() method"); 
        // Get ServletContext using event
        ServletContext sc = event.getServletContext(); 
        // First time in so create context attribute from init parameter
       String strCount = sc.getInitParameter("counter");
       
        if (strCount != null) { 
            // Retrieve and convert number to int type
            try {
                int count = Integer.parseInt(strCount);
                sc.setAttribute("counter", count);
                System.out.println("Context attribute added. Name: counter  Value: " + count);
            } catch(NumberFormatException ex) {
            }
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) { 
        // Write to console
        System.out.println("Within the contextDestroyed() method"); 
    }
}

Compiling ImplServletContextListener

Open your command line editor:

Change to directory  c:\_ServletsAdv\requestlisteners\src\controller

Compile ImplServletContextListener.java using the java compiler with the -cp and -d options as below, making sure you change apache-tomcat-6.0.37 to wherever you downloaded Tomcat to.

javac -cp c:\apache-tomcat-6.0.37\lib\servlet-api.jar -d ..\..\classes ImplServletContextListener.java

The following screenshot shows that we get a clean compile and also the ImplServletContextListener class now compiled into the classes\controller directory.

compile ImplServletContextListener class
Coding ImplServletRequestListener

We are now ready to code our request listeners and we will code the ServletRequestListener implementation first. The ImplServletRequestListener class implements the requestInitialized() and requestDestroyed() methods of the ServletRequestListener interface.

On request scope entry we output messages to the console and use the 'counter' context attribute to create a 'counter' request attribute.

On request scope exit we output messages to the console and use the 'counter' request attribute to update the 'counter' context attribute for use in the next request.

Cut and paste the following code into your text editor and save in the   c:\_ServletsAdv\requestlisteners\src\controller directory as ImplServletRequestListener.java.


package controller;
import javax.servlet.*;

public class ImplServletRequestListener implements ServletRequestListener {

    @Override
    public void requestInitialized(ServletRequestEvent event) { 
        // Write to console
        System.out.println("Within the requestInitialized() method"); 
        System.out.println("Updating request scope from context scope"); 
        // Get ServletContext using event
        ServletContext sc = event.getServletContext(); 
        // Get counter context attribute and store in field 
        int count = (int) sc.getAttribute("counter"); 
        // Get ServletRequest using event
        ServletRequest sr = event.getServletRequest(); 
        // Set ServletRequest attribute
        sr.setAttribute("counter", count);
    }

    @Override
    public void requestDestroyed(ServletRequestEvent event) { 
        // Write to console
        System.out.println("Within the requestDestroyed() method"); 
        System.out.println("Updating context scope from request scope"); 
        // Get ServletRequest using event
        ServletRequest sr = event.getServletRequest(); 
        // Get counter request attribute and store in field
        int count = (int) sr.getAttribute("counter"); 
        // Get ServletContext using event
        ServletContext sc = event.getServletContext(); 
        // Set ServletContext attribute
        sc.setAttribute("counter", count);
    }
}

Compiling ImplServletRequestListener

Open your command line editor:

Change to directory  c:\_ServletsAdv\requestlisteners\src\controller

Compile ImplServletRequestListener.java using the java compiler with the -cp and -d options as below, making sure you change apache-tomcat-6.0.37 to wherever you downloaded Tomcat to.

javac -cp c:\apache-tomcat-6.0.37\lib\servlet-api.jar -d ..\..\classes ImplServletRequestListener.java

The following screenshot shows that we get a clean compile and also the ImplServletRequestListener class now compiled into the classes\controller directory.

compile ImplServletRequestListener class
Coding ImplServletRequestAttributeListener

Our second request listener is for the implementation of the ServletRequestAttributeListener interface. The ImplServletRequestAttributeListener class implements the attributeAdded(), attributeRemoved() and attributeReplaced() methods of the ServletRequestAttributeListener interface. We write the name of the request parameter and its old or new value to the console along with information about the method used.

Cut and paste following code into your text editor and save in the   c:\_ServletsAdv\requestlisteners\src\controller directory as ImplServletRequestAttributeListener.java.


package controller;
import javax.servlet.*;

public class ImplServletRequestAttributeListener implements ServletRequestAttributeListener {

    @Override
    public void attributeAdded(ServletRequestAttributeEvent event) { 
        // Write to console
        System.out.println("Within the request attributeAdded() method"); 
        // Get attribute name and value and write to console
        String attrName = event.getName();
        int count = (int) event.getValue();
        System.out.println("Request attribute added. Name: " + attrName + " Value: " + count);
    }

    @Override
    public void attributeRemoved(ServletRequestAttributeEvent event) { 
        // Write to console
        System.out.println("Within the request attributeRemoved() method"); 
        // Get attribute name and value
        String attrName = event.getName();
        int count = (int) event.getValue();
        System.out.println("Request attribute removed. Name: " + attrName + " Value: " + count);
    }

    @Override
    public void attributeReplaced(ServletRequestAttributeEvent event) { 
        // Write to console
        System.out.println("Within the request attributeReplaced() method"); 
        // Get attribute name and value
        String attrName = event.getName();
        int count = (int) event.getValue();
        System.out.println("Request attribute replaced. Name: " + attrName + " Old value: " + count);
    }
}

Compiling ImplServletRequestAttributeListener

Open your command line editor:

Change to directory  c:\_ServletsAdv\requestlisteners\src\controller

Compile ImplServletRequestListener.java using the java compiler with the -cp and -d options as below, making sure you change apache-tomcat-6.0.37 to wherever you downloaded Tomcat to.

javac -cp c:\apache-tomcat-6.0.37\lib\servlet-api.jar -d ..\..\classes ImplServletRequestAttributeListener.java

The following screenshot shows that we get a clean compile and also the ImplServletRequestAttributeListener class now compiled into the classes\controller directory.

compile ImplServletRequestAttributeListener class

Coding The CounterServlet Classgo to top of page Top

What we are going to do is create a simple form where the user can add to a counter by pressing the submit button.

On entry to request scope we will create a counter request attribute from the counter context attribute and add 10 to it. We will then display the count within the form.

On submission we will add 10 to the counter request attribute.

Cut and paste the following code into your text editor and save it in the
  c:\_ServletsAdv\requestlisteners\src\controller directory as CounterServlet.java.


package controller;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;

public class CounterServlet extends HttpServlet {

    private static final long serialVersionUID = 871964L;

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException { 
        // Get counter context attribute and create counter request attribute
        int count = (int) getServletContext().getAttribute("counter");
        count = count + 10;
        req.setAttribute("counter", count); 
        // Create a simple form with a counter
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.print("<html><head><title>Simple Counter</title></head>" + 
                "<body><h1>Simple Counter Form</h1><form action='' method='post'>" +
                "<fieldset style='background-color:silver;border:1px solid black;" +
                "padding:5px;text-align:left;width:600px;'>" +
                "<legend>Add To Counter</legend>" +
                "<table><tr><td>Counter Value: " + count + "</td></tr>" +
                "<tr><td><input type='submit' value='Submit' /></td></tr>" +
                "</table<fieldset></form></body></html>");
    }

    public void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        // Update Counter
        int count = (int) req.getAttribute("counter");
        count = count + 10;
        req.setAttribute("counter", count); 
        // Resend form with counter updated message
        resp.setContentType("text/html");
        PrintWriter writer = resp.getWriter();
        writer.print("<html><head><title>Simple Counter</title></head>" + 
                "<body><h1>Simple Counter Form</h1><form action='' method='post'>" +
                "<fieldset style='background-color:silver;border:1px solid black;" +
                "padding:5px;text-align:left;width:600px;'>" +
                "<legend>Add To Counter</legend>" +
                "<table><tr><td>Counter Value: " + count + "</td></tr>" +
                "<tr><td><input type='submit' value='Submit' /></td></tr>" +
                "</table<fieldset></form></body></html>");
    }
}


Compiling The CounterServlet Class

Open your command line editor:

Change to directory  c:\_ServletsAdv\requestlisteners\src\controller

Compile CounterServlet.java using the java compiler with the -cp and -d options as below, making sure you change apache-tomcat-6.0.37 to wherever you downloaded Tomcat to.

  javac -cp c:\apache-tomcat-6.0.37\lib\servlet-api.jar -d ..\..\classes CounterServlet.java

The following screenshot shows that we get a clean compile and also the CounterServlet class now compiled into the classes\controller directory.

compile CounterServlet class

Coding The DDgo to top of page Top

There are no DD entries for this application that we haven't seen before.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                             http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
   <context-param>
      <param-name>counter</param-name>
      <param-value>25</param-value>
   </context-param>
   <listener>
      <listener-class>controller.ImplServletContextListener</listener-class>
   </listener>
   <listener>
      <listener-class>controller.ImplServletRequestListener</listener-class>
   </listener>
   <listener>
      <listener-class>controller.ImplServletRequestAttributeListener</listener-class>
   </listener>
   <servlet>
      <servlet-name>ReqListeners</servlet-name>
      <servlet-class>controller.CounterServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>ReqListeners</servlet-name>
      <url-pattern>/example</url-pattern>
   </servlet-mapping>
</web-app>

Save the web.xml file in the DD folder.

Tomcat Deploymentgo to top of page Top

Go to your Tomcat installation which in my case is:

C:\apache-tomcat-6.0.37\webapps\

Within the webapps folder create a folder for our web application called requestlisteners

Within the requestlisteners folder create the WEB-INF folder.

Copy the web.xml file and the classes directory and contents from our development environment into the WEB-INF folder.

After creating these folders and copying the files from development your Tomcat directory structure within the webapps\requestlisteners folder should look something like the following screenshot:

Tomcat directory structure
Testing Our Servletgo to top of page Top

Open a command prompt and change the directory to the location of our Tomcat 6 bin directory and then type in startup (Windows 7) or startup.sh (Linux/Unix/OSX). Press Enter and the Tomcat 6 server should open up in a new window.

You can also start up Tomcat by double-clicking the startup batch file within your Tomcat /bin folder.

Ok we should see some entries in the Tomcat 6 logs on deployment as we adde a ServletContextListener for context initialisation with some console messages. This listener is for the application and will be invoked before any servlets are initialised. The following screenshot shows the System.out.println messages we sent to the console, which appear in the Tomcat 6 server window. I have highlighted the relevant lines in yellow so you can see them easier.

  1. For application startup via the implemented ServletContextListener.
Deploy requestlisteners App

With Tomcat up and running type the following into your web browser address bar and press enter:

  http://localhost:8080/requestlisteners/example

The web browser should be directed to the CounterServlet servlet class within Tomcat and execute. We should see the simple form we created with the 'submit' button to increment the counter as shown in the following screenshot:

Deploy requestlisteners App

We should also see some new entries in the Tomcat 6 logs (at the bottom) as we added listeners for request attribute addition, replacement and removal. The following screenshot shows the System.out.println messages we sent to the console from the ImplServletRequestListener and ImplServletRequestAttributeListener implementations. These appear in the Tomcat 6 server window and we have pressed the 'submit' button a couple of times. I have highlighted the relevant lines in yellow so you can see them easier.

Click CounterServlet

Lesson 2 Complete

In this lesson we looked at request listeners and some uses for them.

What's Next?

In the next lesson we take a final look at listeners by investigating session listeners, their event types and how to use them.

go to home page Homepage go to top of page Top