Oracle® Containers for J2EE Servlet Developer's Guide 10g (10.1.3.1.0) Part Number B28959-01 |
|
|
View PDF |
The servlet specification includes features to track key events in your Web applications through event listeners, which were introduced in "When to Use Event Listeners for Servlet Notification". You can use listeners for automated processing and more efficient resource management based on event status. You can implement listeners for request events, session events, and servlet context events. This is described in the following sections:
There are eight event listener categories:
Servlet context lifecycle (startup or shutdown)
Servlet context attribute changes (adding, deleting, or replacing)
Session lifecycle (startup, invalidation, or timeout)
Session attribute changes (adding, deleting, or replacing)
Session migration (activation or passivation)
Session object binding (objects being bound to or unbound from a session)
Request lifecycle (start of request processing)
Request attribute changes (adding, deleting, or replacing)
You can create one or more event listener classes for each of these event categories. Or, a single listener class can monitor multiple event categories.
Create an event listener class by implementing the appropriate interface or interfaces of the javax.servlet
or javax.servlet.http
package. Table 5-1 summarizes the categories and their associated interfaces.
Table 5-1 Event Listener Categories and Interfaces
Event Category | Event Descriptions | Java Interface |
---|---|---|
Servlet context lifecycle |
Servlet context creation, at which point the first request can be serviced Imminent shutdown of the servlet context |
javax.servlet. ServletContextListener |
Servlet context attributes |
Addition of servlet context attributes Removal of servlet context attributes Replacement of servlet context attributes |
javax.servlet. ServletContextAttributeListener |
Session lifecycle |
Session creation Session invalidation Session timeout |
javax.servlet.http. HttpSessionListener |
Session attributes |
Addition of session attributes Removal of session attributes Replacement of session attributes |
javax.servlet.http. HttpSessionAttributeListener |
Session migration |
Session activation Session passivation |
javax.servlet. HttpSessionActivationListener |
Session object binding |
Object bound to session Object unbound from session |
javax.servlet. HttpSessionBindingListener |
Request lifecycle |
Start of request processing |
javax.servlet. ServletRequestListener |
Request attributes |
Addition of session attributes Removal of session attributes Replacement of session attributes |
javax.servlet. ServletRequestAttributeListener |
Configure a listener through a <listener>
element (subelement of the <web-app>
element) in the web.xml
file. See "Configure the Listener".
After your application starts up and before it services the first request, the servlet container creates and registers an instance of each listener class that is declared in web.xml
. For each event category, listeners are registered in the order in which they are declared. Then, as the application runs, event listeners for each category are invoked in the order of their registration. All listeners remain active until after the last request is serviced for the application.
This section documents methods of the interfaces that are summarized in Table 5-1. Each method described here is called by the servlet container when the appropriate event occurs. These methods take different types of event objects as input, so these event classes and their methods are also discussed.
The ServletContextListener
interface specifies the following methods. Implement this interface in a class you will use for tracking servlet context lifecycle events.
void contextInitialized(ServletContextEvent sce)
The servlet container calls this method when the servlet context has been created and the application is ready to process requests.
void contextDestroyed(ServletContextEvent sce)
The servlet container calls this method when the application is about to be shut down.
The servlet container creates a javax.servlet.ServletContextEvent
object that is input for calls to ServletContextListener
methods. The ServletContextEvent
class includes the following method, which your listener can call:
ServletContext getServletContext()
Use this method to retrieve the servlet context object that was created or is about to be shut down, from which you can obtain information as desired. See "Servlet Contexts: the Application Container" for information about the javax.servlet.ServletContext
interface.
The ServletContextAttributeListener
interface specifies the following methods. Implement this interface in a class you will use for tracking servlet context attribute events.
void attributeAdded(ServletContextAttributeEvent scae)
The servlet container calls this method when an attribute is added to the servlet context.
void attributeRemoved(ServletContextAttributeEvent scae)
The servlet container calls this method when an attribute is removed from the servlet context.
void attributeReplaced(ServletContextAttributeEvent scae)
The servlet container calls this method when an attribute is replaced (its value changed) in the servlet context.
The container creates a javax.servlet.ServletContextAttributeEvent
object that is input for calls to ServletContextAttributeListener
methods. The ServletContextAttributeEvent
class includes the following methods, which your listener can call:
String getName()
Use this method to get the name of the attribute that was added, removed, or replaced.
Object getValue()
Use this method to get the value of the attribute that was added, removed, or replaced. In the case of an attribute that was replaced, this method returns the old value, not the new value.
The HttpSessionListener
interface specifies the following methods. Implement this interface in a listener class you will use to track session lifecycle events.
void sessionCreated(HttpSessionEvent hse)
The servlet container calls this method when the session is created.
void sessionDestroyed(HttpSessionEvent hse)
The servlet container calls this method when the session is about to be terminated.
The container creates a javax.servlet.http.HttpSessionEvent
object that is input for calls to HttpSessionListener
methods. The HttpSessionEvent
class includes the following method, which your listener can call:
HttpSession getSession()
Use this method to retrieve the session object that was created or is about to be terminated, from which you can obtain information as desired.
The HttpSessionAttributeListener
interface specifies the following methods. Implement this interface in a listener class you will use to track session attribute events.
void attributeAdded(HttpSessionBindingEvent hsbe)
The servlet container calls this method when an attribute is added to the session.
void attributeRemoved(HttpSessionBindingEvent hsbe)
The servlet container calls this method when an attribute is removed from the session.
void attributeReplaced(HttpSessionBindingEvent hsbe)
The servlet container calls this method when an attribute is replaced (its value changed) in the session.
The container creates a javax.servlet.http.HttpSessionBindingEvent
object that is input for calls to HttpSessionAttributeListener
methods. The HttpSessionBindingEvent
class includes the following methods, which your listener can call:
String getName()
Use this method to get the name of the attribute that was added, removed, or replaced.
Object getValue()
Use this method to get the value of the attribute that was added, removed, or replaced. In the case of an attribute that was replaced, this method returns the old value, not the new value.
HttpSession getSession()
Use this method to retrieve the session object that had the attribute change.
The HttpSessionActivationListener
interface specifies the following methods. Implement this interface in a listener class you will use to track session migration (activation or passivation) events.
void sessionDidActivate(HttpSessionEvent hse)
The servlet container calls this method when the session is activated.
void sessionWillPassivate(HttpSessionEvent hse)
The servlet container calls this method when the session is about to be passivated.
The servlet container creates an instance of the HttpSessionEvent
class to use as input for HttpSessionActivationListener
method calls. See "HttpSessionListener Methods, HttpSessionEvent Class" for information about this class.
The HttpSessionBindingListener
interface specifies the following methods. Implement this interface in a class whose instances will be bound to a session.
void valueBound(HttpSessionBindingEvent hsbe)
The servlet container calls this method when the object (that implements HttpSessionBindingListener
) is bound to a session, which is identified.
void valueUnbound(HttpSessionBindingEvent hsbe)
The servlet container calls this method when the object is unbound from a session, which is identified. The object can be unbound explicitly, or as a result of session invalidation or timeout.
The servlet container creates an instance of the HttpSessionBindingEvent
class to use as input for HttpSessionBindingListener
method calls. See "HttpSessionAttributeListener Methods, HttpSessionBindingEvent Class" for information about this class.
The ServletRequestListener
interface specifies the following methods. Implement this interface in a listener class you will use to track request lifecycle events.
void requestInitialized(ServletRequestEvent sre)
The servlet container calls this method when the request is about to come into scope of the Web application.
void requestDestroyed(ServletRequestEvent sre)
The servlet container calls this method when the request is about to go out of scope of the Web application.
The container creates a javax.servlet.ServletRequestEvent
object that is input for calls to ServletRequestListener
methods. The ServletRequestEvent
class includes the following method, which your listener can call:
ServletRequest getServletRequest()
Use this method to retrieve the servlet request whose status is changing.
ServletContext getServletContext()
Use this method to retrieve the servlet context of the Web application.
The ServletRequestAttributeListener
interface specifies the following methods. Implement this interface in a listener class you will use to track request attribute events.
void attributeAdded(ServletRequestAttributeEvent srae)
The servlet container calls this method when an attribute is added to the request.
void attributeRemoved(ServletRequestAttributeEvent srae)
The servlet container calls this method when an attribute is removed from the request.
void attributeReplaced(ServletRequestAttributeEvent srae)
The servlet container calls this method when an attribute is replaced (its value changed) in the request.
The container creates a javax.servlet.ServletRequestAttributeEvent
object that is input for calls to ServletRequestAttributeListener
methods. The ServletRequestAttributeEvent
class includes the following methods, which your listener can call:
String getName()
Use this method to get the name of the attribute that was added, removed, or replaced.
Object getValue()
Use this method to get the value of the attribute that was added, removed, or replaced. In the case of an attribute that was replaced, this method returns the old value, not the new value.
This section describes the basic steps of implementing and configuring listeners. See "Session Lifecycle Listener Example" for a complete example.
A listener class can be used for any or all categories of events summarized in "Overview of How Event Listeners Work". A single class can implement multiple listeners. Implement code as follows:
For a servlet context lifecycle listener, implement the ServletContextListener
interface and write code for the methods contextInitialized()
(for actions at application startup) and contextDestroyed()
(for actions at application shutdown), as appropriate.
For a servlet context attribute listener, implement the ServletContextAttributeListener
interface and write code for the methods attributeAdded()
(for actions when an attribute is added), attributeRemoved()
(for actions when an attribute is removed), and attributeReplaced()
(for actions when an attribute value is changed), as appropriate.
For a session lifecycle listener, implement the HttpSessionListener
interface and write code for one the methods sessionCreated()
(for actions at session creation) and sessionDestroyed()
(for actions at session invalidation), as appropriate. See "Write the Session Lifecycle Listener Code" for an elementary example.
For a session attribute listener, implement the HttpSessionAttributeListener
interface and write code for the methods attributeAdded()
, attributeRemoved()
, and attributeReplaced()
, as appropriate.
For a session migration listener, implement the HttpSessionActivationListener
interface and write code for the methods sessionDidActivate()
(for actions at session activation) and sessionWillPassivate()
(for actions at session passivation), as appropriate.
For a session binding listener, implement the HttpSessionBindingListener
interface and write code for the methods valueBound()
(for actions when the object is bound to the session) or valueUnbound()
(for actions when the object is unbound from the session), as appropriate.
For a request lifecycle listener, implement the ServletRequestListener
interface and write code for the methods requestInitialized()
(for actions when the request comes into scope) and requestDestroyed()
(for actions when the request goes out of scope), as appropriate.
For a request attribute listener, implement the ServletRequestAttributeListener
interface and write code for the methods attributeAdded()
, attributeRemoved()
, and attributeReplaced()
, as appropriate.
Notes:
|
To configure each listener class, use a <listener>
element (subelement of <web-app>
) and its <listener-class>
subelement in the application web.xml
file:
<web-app> <listener> <listener-class>SessionLifeCycleEventExample</listener-class> </listener> ... <servlet> <servlet-name>name</servlet-name> <servlet-class>class</servlet-class> </servlet> ... <servlet-mapping> <servlet-name>name</servlet-name> <url-pattern>path</url-pattern> </servlet-mapping> ... </web-app>
A listener is not associated with any particular servlet. At application startup, for each event category, the servlet container registers listeners in the order in which they are declared in web.xml
. As the application runs, event listeners for each category are invoked in the order of their registration whenever an applicable event occurs. Listeners remain active until the last request for the application has been serviced.
Upon application shutdown, however, listeners are notified in the reverse order of their declarations, with request and session listeners being notified before servlet context listeners.
A physical file must be present for a welcome file to dispatch to a servlet. To create a servlet mapped to /index.html
that maps to the JSP page /index.jsp
and have it serve as a welcome file, the web.xml
file should include the following entries:
<servlet> <servlet-name> index_jsp </servlet-name> <jsp-file> /index.jsp </jsp-file> </servlet> <servlet-mapping> <servlet-name>index_jsp</servlet-name> <url-pattern>/index.html</url-pattern> </servlet-mapping>
This works only if there is a physical file, /index.html
, in the Web application. The file can be zero length. As long as the file exists, this servlet will be loaded as the welcome file. Otherwise, a java.lang.StringIndexOutOfBoundsException
exception will be thrown.
This is an elementary example of a session lifecycle event listener that writes messages to the OC4J console whenever a session is created or terminated. There is code for the following components:
index.jsp
: This is the application welcome page, which has a link to invoke SessionCreateServlet
to create an HTTP session.
SessionCreateServlet
: This servlet creates an HTTP session and has a link to SessionDestroyServlet
to terminate the session.
SessionDestroyServlet
: This servlet terminates the HTTP session and has a link back to the welcome page.
SessionLifeCycleEventExample
: This is the event listener class, which implements the HttpSessionListener
interface with code for the sessionCreated()
and sessionDestroyed()
methods to write a console message when a session is created or terminated.
Here is the JSP welcome page, index.jsp
, from which you can invoke the session creation servlet by clicking the Create New Session link. In this example, we assume /mylistener
is the context path of the application, and mysessioncreate
is configured in web.xml
to be the servlet path of the session creation servlet.
<%@page session="false" %> <HTML> <BODY> <H2>OC4J Session Event Listener</H2> <P> This example demonstrates the use of a session event listener. </P> <P> <a href="/mylistener/mysessioncreate">Create New Session</A><br><br> </P> <P> Click the <b>Create</b> link above to start a new session.<br> A session listener has been configured for this application.<br> The servlet container will send an event to this listener when a new session is<br> created or destroyed. The output from the event listener will be visible in the<br> console window from where OC4J was started. </P> </BODY> </HTML>
This servlet, SessionCreateServlet
, creates an HTTP session object and displays some information for the created session. You can terminate the session by clicking the Destroy Session link, which invokes SessionDestroyServlet
. In this example, we assume /mylistener
is the context path of the application, and mysessiondestroy
is configured in web.xml
to be the servlet path of the session invalidation servlet.
import java.io.*; import java.util.Enumeration; import java.util.Date; import javax.servlet.*; import javax.servlet.http.*; public class SessionCreateServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Get the session object. HttpSession session = req.getSession(true); // Set content type for the response. res.setContentType("text/html"); // Then write the data of the response. PrintWriter out = res.getWriter(); out.println("<HTML><BODY>"); out.println("<A HREF=\"/mylistener/mysessiondestroy\">Destroy Session</A>"); out.println("<h2>Session Created</h2>"); out.println("Also check the OC4J console."); out.println("<h3>Session Data:</h3>"); out.println("New Session: " + session.isNew()); out.println("<br>Session ID: " + session.getId()); out.println("<br>Creation Time: " + new Date(session.getCreationTime())); out.println("</BODY></HTML>"); } }
This servlet, SessionDestroyServlet
, destroys the HTTP session object. You can go back to the JSP welcome page to create a new session by clicking the Reload Welcome Page link. In this example, we assume /mylistener
is the context path of the application.
import java.io.*; import java.util.Enumeration; import java.util.Date; import javax.servlet.*; import javax.servlet.http.*; public class SessionDestroyServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { // Get the session object. HttpSession session = req.getSession(true); // Invalidate the session. session.invalidate(); // Set content type for response. res.setContentType("text/html"); // Then write the data of the response. PrintWriter out = res.getWriter(); out.println("<HTML><BODY>"); out.println("<A HREF=\"/mylistener/index.jsp\">Reload Welcome Page</A>"); out.println("<h2>Session Destroyed</h2>"); out.println("Also check the OC4J console."); out.println("</BODY></HTML>"); out.close(); } }
This section shows the session lifecycle listener class, SessionLifeCycleEventExample
, which implements the HttpSessionListener
interface. Its sessionCreated()
method is called by the servlet container whenever an HTTP session is created, which occurs when you click Create New Session from the JSP welcome page. When sessionCreated()
is called, it writes a "CREATED" message to the OC4J console indicating the ID of the new session.
The sessionDestroyed()
method is called by the servlet container whenever an HTTP session is destroyed, which occurs when you click Destroy Session from the session creation servlet. When sessionDestroyed()
is called, it prints a "DESTROYED" message to the OC4J console indicating the ID of the terminated session.
(This class also implements the ServletContextListener
interface and has contextInitialized()
and contextDestroyed()
methods, but these features are not used in this example.)
import javax.servlet.http.*; import javax.servlet.*; public class SessionLifeCycleEventExample implements ServletContextListener, HttpSessionListener { ServletContext servletContext; /* Methods for the ServletContextListener */ public void contextInitialized(ServletContextEvent sce) { servletContext = sce.getServletContext(); } public void contextDestroyed(ServletContextEvent sce) { } /* Methods for the HttpSessionListener */ public void sessionCreated(HttpSessionEvent hse) { log("CREATED",hse); } public void sessionDestroyed(HttpSessionEvent hse) { log("DESTROYED",hse); } protected void log(String msg, HttpSessionEvent hse) { String _ID = hse.getSession().getId(); log("SessionID: " + _ID + " " + msg); } protected void log(String msg) { System.out.println(getClass().getName() + " " + msg); } }
The servlets and the event listener are declared in the web.xml
file. This results in SessionLifeCycleEventExample
being instantiated and registered upon application startup. Because of this, the servlet container automatically calls SessionLifeCycleEventExample methods, as appropriate, upon the occurrence of session lifecycle events (or servlet context lifecycle events, but that is not relevant for this example). Here are the web.xml
entries:
<?xml version="1.0" ?>
<!DOCTYPE web-app (doctype...)>
<web-app>
<listener>
<listener-class>SessionLifeCycleEventExample</listener-class>
</listener>
<servlet>
<servlet-name>sessioncreate</servlet-name>
<servlet-class>SessionCreateServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>sessiondestroy</servlet-name>
<servlet-class>SessionDestroyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sessioncreate</servlet-name>
<url-pattern>mysessioncreate</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>sessiondestroy</servlet-name>
<url-pattern>mysessiondestroy</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
The WAR file for this example, which we name sessionlistener.war
, has the following contents and structure:
index.jsp META-INF/Manifest.mf WEB-INF/web.xml WEB-INF/classes/SessionCreateServlet.class WEB-INF/classes/SessionCreateServlet.java WEB-INF/classes/SessionDestroyServlet.class WEB-INF/classes/SessionDestroyServlet.java WEB-INF/classes/SessionLifeCycleEventExample.class WEB-INF/classes/SessionLifeCycleEventExample.java
And the EAR file is as follows:
sessionlistener.war META-INF/application.xml META-INF/Manifest.mf
(The Manifest.mf
files are created automatically by the JAR utility.)
For this example, assume that application.xml
maps the context path /mylistener
to sessionlistener.war
. In this case, after deployment, you invoke the JSP welcome page as follows:
http://host:port/mylistener/index.jsp
The welcome page outputs the following:
Clicking Create New Session invokes the session creation servlet. In a test run, this results in the following output:
And the OC4J console reports the following:
04/05/13 15:56:25 SessionLifeCycleEventExample Session ID: 8223afa422b84b94235252164cb9a7ad84089f1abe70 CREATED
Clicking Destroy Session invokes the session termination servlet. This results in the following output:
And in a test run, the OC4J console reports the following:
04/05/13 15:58:08 SessionLifeCycleEventExample Session ID: 8223afa422b84b94235252164cb9a7ad84089f1abe70 DESTROYED
Clicking Reload Welcome Page takes you back to the JSP welcome page, where you can create another session.