Since it’s possible that an HttpSession can migrate from one VM to another, the spec designers thought it would be nice if someone bothered to tell the attributes within the session that they, too, were about to move. That way the attributes can make sure they’ll survive the trip.
If all your attributes are straightforward Serializable objects that don’t care where they end up, you’ll probably never use this listener. In fact, we’re guessing 95.324% of all web apps never use this listener. But it’s there if you need it, and the most likely use of this listener is to give attributes a chance to make their instance variables ready for Serialization.
Session migration and Serialization
Now it gets a little tricky...
A Container is required to migrate Serializable attributes (which assumes that all instance variables within the attribute are either Serializable or null).
But a Container is not required to use Serialization as the means for migrating the HttpSession object!
What does this mean to you? Simple: make sure your attribute class types are Serializable and you never have to worry about it. But if they’re not Serializable (which could be because one of the attribute object’s instance variables is not Serializable), have your attribute object class implement HttpSessionActivationListener and use the activation/passivation callbacks to work around it.
The Container is not REQUIRED to use Serialization, so there’s no guarantee that readObject() and writeObject() will be called on a Serializable attribute or one of its instance variables!
If you’re familiar with Serialization, you know that a class that implements Serializable can also choose to implement a writeObject() method, called by the VM whenever an object is serialized, and a readObject() method, called when an object is deserialized. A Serializable object can use these methods to, for example, set non-Serializable fields to null during Serialization (writeObject()) and then restore the fields during deserialization (readObject()). (If you’re NOT familiar with the details of Serialization, don’t worry about it.) But the methods won’t necessarily be called during session migration! So if you need to save and restore instance variable state in your attribute, use HttpSessionActivationListener, and use the two event call-backs (sessionDidActivate() and sessionWillPassivate()) the way you’d use readObject() and writeObject().
Over the next three pages, pay attention to the event object types and to whether the listener is also an attribute class.
Session counter
This listener lets you keep track of the number of active sessions in this web app. Very simple.
Configuring the listener in the DD
<web-app ...> ... <listener> <listener-class> com.example.BeerSessionCounter </listener-class> </listener> </web-app>
This listener lets you track each time any attribute is added to, removed from, or replaced in a session.
Configuring the listener in the DD
<web-app ...> ... <listener> <listener-class> com.example.BeerAttributeListener </listener-class> </listener> </web-app>
Attribute class (listening for events that affect IT)
This listener lets an attribute keep track of events that might be important to the attribute itself—when it’s added to or removed from a session, and when the session migrates from one VM to another.
Listener interface/methods | Event type | Usually implemented by | |
---|---|---|---|
You want to know how many concurrent users there are. In other words, you want to track the active sessions. | HttpSessionListener (javax.servlet.http) sessionCreated sessionDestroyed | HttpSessionEvent | |
You want to know when a session moves from one VM to another. | HttpSessionActivationListener (javax.servlet.http) sessionDidActivate sessionWillPassivate | HttpSessionEvent | |
You have an attribute class (a class for an object that will be used as an attribute value) and you want objects of this type to be notified when they are bound to or removed from a session. | HttpSessionBindingListener (javax.servlet.http) valueBound valueUnbound | HttpSessionBindingEvent | |
You want to know when any session attribute is added, removed, or replaced in a session. | HttpSessionAttributeListener (javax.servlet.http) attributeAdded attributeRemoved attributeReplaced | HttpSessionBindingEvent |
Some of the session-related events don’t follow the event naming conventions!
HttpSessionListener methods take Http SessionEvents. HttpSessionBindingListener methods take HttpSession BindingEvents. BindingEvents. But HttpSessionAttributeListener methods take HttpSession And HttpSessionActivationListener methods take Http SessionEvents. Since HttpSessionEvent and HttpSessionBindingEvent classes worked perfectly well, there was no need for the API to add two more event classes.