Difference between HttpSessionAttributeListener and HttpSessionBindingListener

Servlet API in Java EE defines different types of event listener interfaces for watching changes in HttpSession. Two of these interfaces namely HttpSessionAttributeListener and HttpSessionBindingListener cause confusion among programmers. These interfaces enable 2 different ways of handling session changes. This article explains each listener with an example.

HttpSessionAttributeListener Interface
A class can implement HttpSessionAttributeListener interface to listen for attributes being added or removed from a session. This class can be configured as a listener using the listener tag in web.xml deployment descriptor or using @WebListener annotation in the class file. This interface has 3 callback methods - attributeAdded, attributeDeleted and attributeReplaced.

HttpSessionBindingListener Interface
An object which is added as session attribute can implement HttpSessionBindingListener interface. This tells the servlet container to call the HttpSessionBindingListener methods defined in the object whenever the object instance is added or removed from session. This is useful when the object itself needs to known when it is being added or removed from session. There is no need to mark this object as listener object using annotations or web.xml entry. It has 2 callback methods - valueBound, valueUnbound.

HttpSessionAttributeListener and HttpSessionBindingListener - Sample Program
The following sample servlet program illustrates the difference between HttpSessionAttributeListener and HttpSessionBindingListener.

The following sample servlet (ListenerDemoServlet) adds multiple attributes to session. One of them (MyObjectInSession) implements HttpSessionBindingListener. Whenever an attribute is added, the configured listener MySessionAttributeListener (which implements HttpSessionAttributeListener) is called. When MyObjectSession is added or removed, container calls MySessionAttributeListener methods AND HttpSessionBindingListener methods defined in MyObjectInSession.

ListenerDemoServlet.java

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet(name = "ListenerDemoServlet", urlPatterns = {"/ListenerDemoServlet"})
public class ListenerDemoServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, 
                         HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.setAttribute("stringvalue1", "hello");
        session.setAttribute("stringvalue2", "world");
        session.setAttribute("objvalue1", new MyObjectInSession());
    }

}

MyObjectInSession.java

package com.quickprogrammingtips.sample.articleproject;

import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

// the listener annotation is optional since container infers it from the interface
public class MyObjectInSession implements HttpSessionBindingListener{
    public MyObjectInSession() {
    }
    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("My Object is added to session: Key is :" 
                           + event.getName());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
    }
}

MySessionAttributeListener.java

package com.quickprogrammingtips.sample.articleproject;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;

// The following annotation marks this class as a listener and container automatically registers it.
@WebListener 
public class MySessionAttributeListener implements HttpSessionAttributeListener {

    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
       System.out.println("Attribute added is "+event.getName());
    }

    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
    }

    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
       System.out.println("Attribute replaced is "+event.getName());
    }
}

When the servlet is run, the following output is seen on the application server console,

Attribute added is stringvalue1
Attribute added is stringvalue2
My Object is added to session: Key is :objvalue1
Attribute added is objvalue1

Summary
HttpSessionAttributeListener is a generic listener for the session and is called whenever any attribute value is added or removed from a session. This enables us to keep track of all the objects that is added or removed from a session. This listener lets us know whether an attribute is added, removed or updated.

HttpSessionBindingListener is a callback interface that can be implemented by classes which are intended to be added to session. Whenever an object implementing HttpSessionBindingListener is added or removed to session, the callback methods defined on the object is called. Unlike HttpSessionAttributeListener it doesn't differentiate between adding or updating an attribute.

The key difference is between HttpSessionAttributeListener and HttpSessionBindingListener is that HttpSessionAttributeListener listens for any attribute change in session while an object implementing HttpSessionBindingListener gets notified whenever the same object is added/removed from session.