During the lifetime of a typical web application, a number of events take place, such as HTTP requests getting created or destroyed, request or session attributes getting added, removed or modified, and so on and so forth.
The servlet API provides a number of listener interfaces we can implement in order to react to these events. All of these interfaces are in the javax.servlet package, and the following table summarizes them:
Listener interface |
Description |
ServletContextListener |
Contains methods for handling context initialization and destruction events. |
ServletContextAttributeListener |
Contains methods for reacting to any attributes added, removed, or replaced in the servlet context (application scope). |
ServletRequestListener |
Contains methods for handling request initialization and destruction events. |
ServletRequestAttributeListener |
Contains methods for reacting to any attributes added, removed, or replaced in the request. |
HttpSessionListener |
Contains methods for handling HTTP session initialization and destruction events. |
HttpSessionAttributeListener |
Contains methods for reacting to any attributes added, removed, or replaced in the HTTP session. |
All we need to do to handle any of the events handled by the interfaces described in the preceding table is to implement one of the previous interfaces and annotate it with the @WebListener interface, or declare it in the web.xml deployment descriptor via the <listener> tag. Unsurprisingly, the ability to use an annotation to register a listener was introduced in version 3.0 of the servlet specification.
The API for all of the preceding interfaces is fairly straightforward and intuitive. We will show an example for one of the preceding interfaces, and the others will be very similar.
The following example illustrates how to implement the ServletRequestListener interface, which can be used to perform an action whenever an HTTP request is created or destroyed:
package net.ensode.javaee8book.listener; import javax.servlet.ServletContext; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; @WebListener() public class HttpRequestListener implements ServletRequestListener
{ @Override public void requestInitialized(ServletRequestEvent
servletRequestEvent) { ServletContext servletContext = servletRequestEvent.getServletContext(); servletContext.log("New request initialized"); } @Override public void requestDestroyed(ServletRequestEvent
servletRequestEvent) { ServletContext servletContext = servletRequestEvent.getServletContext(); servletContext.log("Request destroyed"); } }
As we can see, all we need to do to activate our listener class is to annotate it with the @WebListener annotation. Our listener must also implement one of the listener interfaces we listed previously. In our example, we chose to implement javax.servlet.ServletRequestListener; this interface has methods that are automatically invoked whenever an HTTP request is initialized or destroyed.
The ServletRequestListener interface has two methods, requestInitialized() and requestDestroyed(). In our previous, simple implementation we simply sent some output to the log, but of course we can do anything we need to do in our implementations.
Deploying our previous listener along with the simple servlet we developed earlier in the chapter, we can see the following output in the application server log:
[2017-05-31T20:15:57.900-0400] [glassfish 5.0] [INFO] [] [javax.enterprise.web] [tid: _ThreadID=109 _ThreadName=http-listener-1(2)] [timeMillis: 1496276157900] [levelValue: 800] [[ WebModule[/servletlistener] ServletContext.log():New request initialized]] [2017-05-31T20:15:58.013-0400] [glassfish 5.0] [INFO] [] [javax.enterprise.web] [tid: _ThreadID=109 _ThreadName=http-listener-1(2)] [timeMillis: 1496276158013] [levelValue: 800] [[
WebModule[/servletlistener] ServletContext.log():Request destroyed]]
Implementing the other listener interfaces is just as simple and straightforward.