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.HttpSessionListener
andjavax.servlet.http.HttpSessionAttributeListener
act 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.HttpSessionEvent
andjavax.servlet.http.HttpSessionBindingEvent
event types respectively. The main difference here is that the event type is not calledHttpSessionAttributeEvent
as is the convention with context and request attribute event types.javax.servlet.http.HttpSessionBindingListener
andjavax.servlet.http.HttpSessionActivationListener
are 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.HttpSessionEvent
andjavax.servlet.http.HttpSessionBindingEvent
event 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
ImplHttpSessionBindingListener
as well asImplHttpSessionAttributeListener
:- The container will always invoke the
valueBound()
method of theImplHttpSessionBindingListener
implementation before theattributeAdded
andattributeReplaced
methods of theImplHttpSessionAttributeListener
implementation. - The container will always invoke the
valueUnbound()
method of theImplHttpSessionBindingListener
implementation after theattributeRemoved
method of theImplHttpSessionAttributeListener
implementation.
- The container will always invoke the
- I let the session time out so you can see the
attributeRemoved
andvalueUnbound()
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.