© Copyright Marcus Green 2007
4.3) Using session listeners, write code to respond to an event when an object is added to a session, and write code to respond to an event when a session object migrates from one VM to another.
Listening to a session can be view from two perspectives, either that of the session, i.e. code that listens for events to happen to a session, or that of the object that may be added to or removed from the session. Thus you might want to count the number of users on a system by watching how many users sessions are created, or you might have a class that can itself track how many times it is added to a session.
The HttpSessionBindingListener interface is implemented by the classes whose instances are added or removed by the session. When an object is added or removed from a session, the container checks the interfaces implemented by the object. If the object implements the HttpSessionBindingListener, the container calls the matching notification method.
The following LoginServlet class is used to add attributes to the session which will trigger events in the (User) object that is added.
/**
* Marcus Green 2006
* Demonstration of Sessions
* The User class writes to
* the console when
* Session binding events
* occur
***/
package com.examulator;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginServlet extends HttpServlet {
String sUserName;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
sUserName = request.getParameter("username");
if(sUserName ==null){
String sUserName = (String) session.getAttribute("username");
/* Create a user with the name passed via the query string */
com.examulator.User user = new com.examulator.User(sUserName);
/*add to the session (will trigger session binding event) */
session.setAttribute("user",user);
}else{
session.setAttribute("username",sUserName);
}
out.print("UserName="+session.getAttribute("username")) ;
}
}
package com.examulator;
import javax.servlet.http.*;
import javax.servlet.*;
public class User implements HttpSessionBindingListener{
private String sUserName;
public User(String sUserName){
this.sUserName = sUserName;
}
public void valueBound(HttpSessionBindingEvent e){
System.out.println(sUserName+" user bound");
}
public void valueUnbound(HttpSessionBindingEvent e){
System.out.println(sUserName+" user unbound");
}
}
It is possible to get access to the session that the Object is being associated with via the getSession method of the HttpSessionBindingEvent. Once you have the session you can then get at the ServletContext. The following code can be added into either valueBound or Unbound to write to the log when an event occurs.
HttpSession session = e.getSession(); ServletContext sc = session.getServletContext(); sc.log(sUserName+"user bound");
The HttpSessionBindingListener does not need to be configured in the deployment descriptor.
|
|
The HttpSessionBindingListener does not need to be configured in the deployment descriptor. |
This interface allows code that watches for changes in session attributes from the perspective of the session rather than the objects that are added to the session. It supports three methods
attributeAdded
attributeRemoved
attributeReplaced
The method names are fairly self explanatory and do approximately what you might expect.
The following code shows how you could monitor when attributes are added to a session.
package com.examulator;
import javax.servlet.http.*;
public class UserAttributeListener implements HttpSessionAttributeListener{
public void attributeAdded(HttpSessionBindingEvent event){
String name = event.getName();
Object value = event.getValue();
System.out.println("Attribute added " + name + " : " + value);
}
public void attributeRemoved(HttpSessionBindingEvent event){}
public void attributeReplaced(HttpSessionBindingEvent event){}
}According to the API docs the HttpSessionListener interface does the following
“Implementations of this interface may are notified of changes to the list of active sessions in a web application. To receive notification events, the implementation class must be configured in the deployment descriptor for the web application.”
The HttpSessionListener interface seems to offer functionality linked more to “housekeeping tasks” rather than end user tasks. It provides the following two methods.
sessionCreated(HttpSessionEvent se) sessionDestroyed(HttpSessionEvent se)
To understand how these can be used you need to understand what can cause a session to be created or destroyed, which is covered in section 4.2. You could use this interface for monitoring statistics for your web site by tracking the creation of sessions. This might give you more information about the number of individual visitors rather than simply monitoring the number of page requests.
package com.examulator;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* @author Marcus Green
* Chapter 03 HttpSessionListener
* Need to open in different browsers
* to show it working. For real world use
* would probably write to log, e.g.
* getServletContext().log("Session Count= "+sessionCount;
*/
public class SessionTrack extends HttpServlet implements HttpSessionListener{
static private int sessionCount;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
PrintWriter out = response.getWriter();
try{
out.println("Session Count= "+sessionCount);
}catch(Exception e){/* should do something here */ }
}
public void sessionCreated(HttpSessionEvent event){
sessionCount++;
}
public void sessionDestroyed(HttpSessionEvent event){
//part of interface so must be defined even if not used
}
}
This would be configured in the deployment descriptor as follows
<listener>
<listener-class>
com.examulator.SessionTrack
</listener-class>
</listener>When creating that example I forgot to configure up the deployment descriptor and spent a frustrating half an hour wondering why my code didn't work.
The term JVM refers to Java Virtual Machine (i.e. the runtime environment that executes the Java bytecode. The HttpSessionActivationListener only has any relevance when a session is part of a web application in a distributed environment. Distributed environments are where the processing is shared over multiple machines, and thus it is possible to deal with very high work loads by simply adding more machines, rather than attempting to upgrade a single machine into a Godzilla configuration.
Distributed applications are generally outside the scope of the exam and are fairly difficult to simulate with free software in the privacy of your own home. This capability is relevant to systems such as IBM WebSphere or BEA WebLogic that support distributed processing.
The JSP/Servlet standard does not require that a web container supports distributed applications, but it must support the HttpSessionActivationListener interface, to allow code to be capable of supporting such an environment. The HttpSessionActivationListener has two methods.
public void sessionDidActivate(HttpSessionEvent se) public void sessionWillPassivate(HttpSessionEvent se)
The specification mandates that a container may migrate a session to another JVM for purposes such as load balancing or fail-over. This type of capability is considered vital for the deployment of large scale web application
Session passivation is where inactive sessions are written to a persistent store. Session activation is the ability to a previously passivated session into memory from the persistent store. For an attributes to be migrated between distributed JVM's any attributes must implement the java.io.Serializable interface. This is not a very taxing programming task as Serializable is a marker interface i.e. it has no methods.
|
|
HttpSessionActivationListener does not require any configuration in the deployment descriptor. |
The Session Activation events do not require any configuration within the deployment descriptor. For the purpose of the exam you just need to know it is possible to monitor the activation and passification session via the HttpSessionActivationListener.
Other sources
API Docs for HttpSessionBindingListener http://java.sun.com/j2ee/sdk_1.2.1/techdocs/api/javax/servlet/http/HttpSessionBindingListener.html
API Docs for
HttpSessionBindingListener
http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/http/HttpSessionAttributeListener.html
This objective according to Mikalai Zaikin
http://java.boot.by/wcd-guide/ch04s03.html