Session ListenersS2C Home « Session Listeners
In our third and final lesson on listeners we take an in-depth look at session listeners, which allow us to be alerted by session state alterations; whether it be when the lifecycle of the session has changed, one of the attributes within a session has been added, removed, replaced, bound, unbound, or when the session has been passivated or activated in a distributed environment.
Knowing when your session is about to come into scope can enhance pre-initialisation of session scoped resources and knowing when your session is about to go out of scope is useful for tidying up the resources. Both situations could also help with keeping track of resources on distributed environments or logging them to know when attributes are added, removed, replaced, bound or unbound.
There are four session listener types we can use:
javax.servlet.http.HttpSessionListenerandjavax.servlet.http.HttpSessionAttributeListeneract in exactly the same way as the context and request listeners we saw in the previous two lessons. When implemented, these types will trigger from thejavax.servlet.http.HttpSessionEventandjavax.servlet.http.HttpSessionBindingEventevent types respectively. The main difference here is that the event type is not calledHttpSessionAttributeEventas is the convention with context and request attribute event types.javax.servlet.http.HttpSessionBindingListenerandjavax.servlet.http.HttpSessionActivationListenerare different to all the other listeners we have seen so far as they are not declared within the DD. When implemented, these types will trigger from thejavax.servlet.http.HttpSessionEventandjavax.servlet.http.HttpSessionBindingEventevent types respectively. These are the same event types as the other two listeners but invoke different methods.
The session 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 |
|---|---|---|
HttpSession | HttpSessionEvent | You want to know when a session is created or destroyed. |
HttpSession | HttpSessionEvent | You want to know when a session is passivated on one JVM and then reactivated on another JVM. |
HttpSession | HttpSession | You want to know when a session attribute has been added, removed or replaced. |
HttpSession | HttpSession | You want to know when objects are bound or unbound from a session. |
We look at each session listener and session event type in more detail in the following sections and finish our discussion of session listeners with some code to see the various components in action.
The HttpSessionListener InterfaceTop
We implement the HttpSessionListener type when we want to receive notifications about changes to the list of active sessions within a web application. This allows users of the
interface to know when a session has been created or invalidated. This type of notification can be useful for any pre-initialization we need to do in the first instance and for any
housekeeping, or persisting of session attributes in the second. We can also use the methods within the interface to keep a count of the active sessions for web applications
in distributed systems for load balancing across several servers.
The two methods within the HttpSessionListener 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 sessionCreated( HttpSessionEvent hse) | Receive notification that a session has been created. |
void sessionDestroyed( HttpSessionEvent hse) | Receive notification that a session is about to be invalidated. |
The HttpSessionActivationListener InterfaceTop
We implement the HttpSessionActivationListener type when we have objects that are bound to a session as session attributes and we want to receive notifications when a session
has been activated or is about to be passivated. Since this interface is implemented by classes bound to a session, each object we want bound to the session as a session attribute needs to
implement the HttpSessionActivationListener type independently. This means that we can't configure this type of listener within the DD as we want the objects that pertain to a
particular session.
But why on earth would we want to have individual classes bound to sessions as attributes and each implementing its own HttpSessionActivationListener type? The answer is distributed
systems. When an application has large amounts of traffic it is common practice to deploy that application over several web servers. Each web server has identical, but independent,
copies of the web application stored on them. When a request comes in from clients they can be passed to whichever server is the least active, which is known as load balancing.
If the client has a session, then the container needs to know about the session so it can recreate the session state for the client on activation and the terminology for this is session migration. With respect to Java, this means that when a session is moved from one JVM to another, or put a different way passivated then activated, then all objects bound to the session are transferred from the first JVM to the second. This is achieved as follows:
- On passivation all session bound objects need to be serialized.
- On activation all session bound objects need to be deserialized.
This of course means that all session bound objects in a distributed application need to implement the java.io.Serializable interface or an exception will occur.
The two methods within the HttpSessionActivationListener interface are shown in the table below.
| Method Declaration | Description |
|---|---|
void sessionDidActivate( HttpSessionEvent hse) | Receive notification that a session has just been activated. |
void sessionWillPassivate( HttpSessionEvent hse) | Receive notification that a session is about to be passivated. |
The HttpSessionEvent ClassTop
HttpSessionEvent is the event class for notifications about changes to sessions within a web application and consists of one method which is used to return the
HttpSession that changed. This class is also the parameter input for the sessionCreated() and sessionDestroyed() methods of the HttpSessionListener
interface and the sessionDidActivate() and sessionWillPassivate() methods of the HttpSessionActivationListener interface. Implementation of either
or both interfaces is how we are alerted to changes when the event is triggered.
The single method within the HttpSessionEvent class is shown in the table below. Click the link in the table below to go to a code example of the implemented method.
| Method Declaration | Description |
|---|---|
HttpSession getSession() | Return the session that changed. |
The HttpSessionAttributeListener InterfaceTop
We implement the HttpSessionAttributeListener type when we want to receive notifications about changes to the attribute list of sessions 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 HttpSessionAttributeListener 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( HttpSessionBinding | Receive notification that a new attribute has been added to a session. |
void attributeRemoved( HttpSessionBinding | Receive notification that an existing attribute has been removed from a session. |
void attributeReplaced( HttpSessionBinding | Receive notification that an existing attribute has been replaced within a session. |
The HttpSessionBindingListener InterfaceTop
We implement the HttpSessionBindingListener type when we want an object is being bound (added) to or unbound (removed) from a session. Since this interface is implemented by
classes bound to a session, each object we want bound to the session as a session attribute needs to implement the HttpSessionBindingListener type independently. This means
that we can't configure this type of listener within the DD as we want the objects that pertain to a particular session. This type of notification can be useful for refreshing rendered
information as we get notified when an object gets rebound to the session and may have changed in the meantime. An object can become unbound programmatically, through a session being
invalidated or when a session times out.
The three methods within the HttpSessionBindingListener 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 valueBound( HttpSessionBinding | Send notification to an object that it is being bound (added) to an identified session. |
void valueUnbound( HttpSessionBinding | Send notification to an object that it is being unbound (removed) from an identified session. |
The HttpSessionBindingEvent ClassTop
HttpSessionBindingEvent is the event class for notifications about objects being bound (added), unbound (removed) or replaced within a session and consists of three
methods which show the key/value pairing of the attribute and session in question. This class is also the parameter input for the attributeAdded(), attributeRemoved()
and attributeReplaced() methods of the HttpSessionAttributeListener interface and the valueBound() and valueUnbound() methods of the
HttpSessionBindingListener interface. Implementation of either or both interfaces is how we are alerted to changes when the event is triggered.
The three methods within the HttpSessionBindingEvent 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 was bound to, or unbound from, the session. |
| HttpSession getSession() | Return the session that changed. |
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 Session ListenersTop
We will keep the idea simple so you can see how the HttpSessionListener HttpSessionAttributeListener and HttpSessionBindingListener listeners are
implemented and what else we need to do to get our listeners working. There is no example of the HttpSessionActivationListener as we are not running a distributed system but
hopefully you got the idea of how to use it above. 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 java Tutor site at Swing - Event Handling.
Within the _ServletsAdv folder create a new folder for this lesson called sessionlisteners
Within the sessionlisteners 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 subfolder called controller.
So after creating these folders your directory structure should look something like the following screenshot:
Coding The ListenersTop
We are now ready to code our listeners which will consist of implementations of the HttpSessionListener, HttpSessionAttributeListener and HttpSessionBindingListener interfaces.
Coding ImplHttpSessionListener
The ImplHttpSessionListener class implements the sessionCreated() and sessionDestroyed() methods of the HttpSessionListener
interface. Within the overridden sessionCreated() and sessionDestroyed() methods we get the HttpSession object using the HttpSessionEvent
object. We then output some session information message to the console.
Cut and paste the following code into your text editor and save in the c:\_ServletsAdv\sessionlisteners\src\controller directory as ImplHttpSessionListener.java.
package controller;
import javax.servlet.http.*;
public class ImplHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
// Write to console
System.out.println("Within the sessionCreated() method");
// Get HttpSession from event
HttpSession sess = event.getSession();
// Write some session information
System.out.println("Unique Session identifier: " + sess.getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
// Write to console
System.out.println("Within the sessionDestroyed() method");
// Get HttpSession from event
HttpSession sess = event.getSession();
// Write some session information
System.out.println("Unique Session identifier: " + sess.getId());
System.out.println("Session removal after: " + sess.getMaxInactiveInterval()
+ " seconds inactivity");
}
}
Compiling ImplHttpSessionListener
Open your command line editor:
Change to directory c:\_ServletsAdv\sessionlisteners\src\controller
Compile ImplHttpSessionListener.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 ImplHttpSessionListener.java
The following screenshot shows that we get a clean compile and also the ImplHttpSessionListener class now compiled into the classes\controller directory.
Coding ImplHttpSessionAttributeListener
The ImplHttpSessionAttributeListener class implements the attributeAdded(), attributeRemoved() and attributeReplaced() methods of the
HttpSessionAttributeListener interface. We write the name of the session parameter and its old or new value to the console along with information about the method used.
Cut and paste the following code into your text editor and save in the c:\_ServletsAdv\sessionlisteners\src\controller directory as ImplHttpSessionAttributeListener.java.
package controller;
import javax.servlet.http.*;
public class ImplHttpSessionAttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent event) {
// Write to console
System.out.println("Within the session attributeAdded() method");
// Get attribute name and value and write to console
String attrName = event.getName();
String val = (String) event.getValue();
System.out.println("Session attribute added. Name: " + attrName + " Value: " + val);
}
@Override
public void attributeRemoved(HttpSessionBindingEvent event) {
// Write to console
System.out.println("Within the session attributeRemoved() method");
// Get attribute name and value
String attrName = event.getName();
String val = (String) event.getValue();
System.out.println("Session attribute removed. Name: " + attrName + " Value: " + val);
}
@Override
public void attributeReplaced(HttpSessionBindingEvent event) {
// Write to console
System.out.println("Within the session attributeReplaced() method");
// Get attribute name and value
String attrName = event.getName();
String val = (String) event.getValue();
System.out.println("Session attribute replaced. Name: " + attrName + " Value: " + val);
}
}
Compiling ImplHttpSessionAttributeListener
Open your command line editor:
Change to directory c:\_ServletsAdv\sessionlisteners\src\controller
Compile ImplHttpSessionAttributeListener.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 ImplHttpSessionAttributeListener.java
The following screenshot shows that we get a clean compile and also the ImplHttpSessionAttributeListener class now compiled into the classes\controller directory.
Coding ImplHttpSessionBindingListener
The ImplHttpSessionBindingListener class implements the valueBound() and valueUnbound() methods of the HttpSessionBindingListener interface.
Remember that bound session objects are not declared in the DD and each will need its own implementation of the HttpSessionBindingListener interface.
On object binding and unbinding we output some messages to the console.
Cut and paste the following code into your text editor and save in the c:\_ServletsAdv\sessionlisteners\src\controller directory as ImplHttpSessionBindingListener.java.
package controller;
import javax.servlet.http.*;
public class ImplHttpSessionBindingListener implements HttpSessionBindingListener {
private String ihsblStr;
// Constructor
public ImplHttpSessionBindingListener(String ihsblStr) {
this.ihsblStr = ihsblStr;
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
// Write to console
System.out.println("Within the session valueBound() method");
// Get and write instance variable to console
System.out.println("Binding object:" + getIhsblStr());
}
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
// Write to console
System.out.println("Within the session valueUnbound() method");
// Get and write instance variable to console
System.out.println("Unbinding object:" + getIhsblStr());
}
// Getter and setter
public String getIhsblStr() {
return ihsblStr;
}
public void setIhsblStr(String ihsblStr) {
this.ihsblStr = ihsblStr;
}
}
Compiling ImplHttpSessionBindingListener
Open your command line editor:
Change to directory c:\_ServletsAdv\sessionlisteners\src\controller
Compile ImplHttpSessionAttributeListener.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 ImplHttpSessionBindingListener.java
The following screenshot shows that we get a clean compile and also the ImplHttpSessionBindingListener class now compiled into the classes\controller directory.
Coding The SessionServlet ClassTop
What we are going to do is create a simple servlet that just creates some bound and not bound session attributes. There is no HTML output for this example as we are using the Tomat 6 logs to check our results.
Cut and paste the following code into your text editor and save it in the c:\_ServletsAdv\sessionlisteners\src\controller directory as SessionServlet.java.
package controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionServlet extends HttpServlet {
private static final long serialVersionUID = 871964L;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
// Get a HttpSession
HttpSession session = request.getSession();
// Add some bound objects
ImplHttpSessionBindingListener boundObj1 = new ImplHttpSessionBindingListener("IHSBL1");
ImplHttpSessionBindingListener boundObj2 = new ImplHttpSessionBindingListener("IHSBL2");
// Add bound objects to session attributes
session.setAttribute("Bound1", boundObj1);
session.setAttribute("Bound2", boundObj2);
// Add some non-bound session attributes
session.setAttribute("non_boundObj1", "Non Bound 1");
session.setAttribute("non_boundObj2", "Non bound 2");
// Remove a bound and non-bound session attributes
session.removeAttribute("Bound2");
session.removeAttribute("non_boundObj2");
}
}
Compiling The SessionServlet Class
Open your command line editor:
Change to directory c:\_ServletsAdv\sessionlisteners\src\controller
Compile SessionServlet.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;..\..\classes -d ..\..\classes SessionServlet.java
The following screenshot shows that we get a clean compile and also the SessionServlet class now compiled into the classes\controller directory.
Coding The DDTop
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">
<listener>
<listener-class>controller.ImplHttpSessionListener</listener-class>
</listener>
<listener>
<listener-class>controller.ImplHttpSessionAttributeListener</listener-class>
</listener>
<servlet>
<servlet-name>SessListeners</servlet-name>
<servlet-class>controller.SessionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessListeners</servlet-name>
<url-pattern>/example</url-pattern>
</servlet-mapping>
</web-app>
Save the web.xml file in the DD folder.
Tomcat DeploymentTop
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 sessionlisteners
Within the sessionlisteners 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\sessionlisteners folder should look something like the following screenshot:
Testing Our ServletTop
Open a command prompt and change the directory to the location of our Tomcat bin directory and then type in startup (Windows 7) or startup.sh (Linux/Unix/OSX).
Press Enter and the Tomcat 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.
With Tomcat up and running type the following into your web browser address bar and press enter:
http://localhost:8080/sessionlisteners/example
We should see some new entries in the Tomcat logs (at the bottom) as we added listeners for session creation, destruction, session attribute addition, replacement, removal, binding and
unbinding. The following screenshot shows the System.out.println messages we sent to the console from the ImplHttpSessionListener, ImplHttpSessionAttributeListener
and ImplHttpSessionBindingListener implementations. These appear in the Tomcat server window and I have highlighted the relevant lines in yellow so you can see them easier.
There are a few points to note when looking at the output:
- When you implement
ImplHttpSessionBindingListeneras well asImplHttpSessionAttributeListener:- The container will always invoke the
valueBound()method of theImplHttpSessionBindingListenerimplementation before theattributeAddedandattributeReplacedmethods of theImplHttpSessionAttributeListenerimplementation. - The container will always invoke the
valueUnbound()method of theImplHttpSessionBindingListenerimplementation after theattributeRemovedmethod of theImplHttpSessionAttributeListenerimplementation.
- The container will always invoke the
- I let the session time out so you can see the
attributeRemovedandvalueUnbound()methods being invoked and their ordering.
Lesson 3 Complete
In this lesson we looked at the various session listeners and when to use them.
What's Next?
In the next lesson we learn all about filters.