Skip to main content

Servlet API Listeners

Generally speaking Listener are objects which are used for performing some action when somethings is happened. They receive notification about some change and perform action registered for that event.
Also in the web application from time to time some "interesting" changes happens, and it would be nice that we can be notified about them. 
Because of that in the servlet api are defined some Listener interfaces which allow us to handle events which are interesting for us.
We can split them in three groups:
  • Context Listeners (responsible for handling context events) 
  • Request Listeners (responsible for handling request events) and
  • Session Listeners (responsible for handling session events)
First i will explain each of listeners type, and at end i will show how to register listener.

Context Listeners

They are responsible for handling events which are happening in context, and with context. During its life context will pass through three life phases (life cycle):
  • Initialization, it is starting when application is deployed, and before any application component is created. Context must exist before any other component is created because it is used by them. 
  • Lifetime,  it is time when application is running and when application context is used by component.
  • Destruction, last phase in context life. It is started when server go to shut down or when application is undeployed.

From time to time it is very helpful to have ability to perform some action when context change its state. 
So to do that you all what you need to do is to make class which implement ServletContextListener interface and register listener in application descriptor (web.xml). This interface provide two methods:
  • void contextInitialized(ServletContextEvent event), called after application is deployed but before any components is created.
  • void contextDestoroyed(ServletContextEvent event), called after all components are destroyed.
This two methods have one parameter of type ServletContextEvent. This class have only one method it is:
  • void ServletContext getServletContext()
which return context. Creation and passing object of this type to the listener is job of web container so we don't need to bother with it.

Beside of listening for context life cycle changes some times we need to listen for changes made on context attributes, in that purpose servlet api define ServletContextAttributeListener. This interface bring three new methods to us which allow us performing of action when attribute changes its states:
  • void attributeAdded(ServletContextAttributeEvent event), 
  • void attributeRemoved(ServletContextAttributeEvent even),
  • void attributeReplaced(ServletContextAttributeEvent event)
This methods are executed when attribute is added to the context, removed from them and when the value is replaced with new one. All of those method have only one parameter of type ServlerContextAttributeEvent which extends ServletContextEvent and brings two new methods:
  • String getName(), return name of attribute
  • Object getValue(), this method depending on performed action on attribute can return new or old attributes value. In case of adding it will retrieve new value, and for other cases it will retrieve old values.


Request Listeners

Request listener are listener which are used for performing action during changes in request life cycle or when request attributes are changed. In servlet api we have defined two kinds of request listener interfaces and those are:
  • ServletRequestListener, responsible for handling events about life cycle changes, and
  • ServletRequestAttributeListener, responsible for events which are fired during some changes on attributes.
ServletRequestListener provide two methods:
  • void requestInitialized(ServletRequestEvent event), it is invoked when request is coming in application scope. This do not imply that request is newly created, just that request is cleared.
  • void requestDestroyed(ServletRequestEvent event), invoked when request leaving application. This does not mean that request is ready for garbage collector, that indicate tha content of request is cleared.
This methods accepts parameter of type ServletRequestEvent which have two methods:
  • ServletContext getServletContext(), retrieve application context
  • ServletRequest getServletRequest(), retrieve request.
ServletRequestAttributeListener is responsible for handling events which notify us that there happened some changes on attributes, in request scope, such as added new attribute, removed attribute and attribute value is changed. So this listener define three new methods:
  • void attributeAdded(ServletRequestAttributeEvent event)
  • void attributeRemoved(ServletRequestAttributeEvent event)
  • void attributeReplaced(ServletRequestAttributeEvent event)
All of this methods take ServletRequestAttributeEvent as its only parameter. ServletRequestAttributeEvent extends ServletRequestEvent and define two new methods:
  • String getName();, name of attribute
  • Object getValue();, new or old value depending on performed action. New value for adding and old value for removing and replacing.

Session Listeners

Listener responsible for interacting with session states and changes in session attributes are called Session listeners. There is a few interface defined for listening session events:
  • HttpSessionListener, listener responsible for performing action when session state is changed.
  • HttpSessionActivationListener, listener responsible for performing action when on session state is changed but on attribute level. 
  • HttpSessionAttributeListener, listener responsible for performing action when there is changes on attributes in session scope. 
  • HttpSessionBindingListener, lister performing action when attribute is added or remove from context, this listener is also implemented on attribute level.
HttpSessionListener interface is responsible for performing action on changing session state. It will be informed by container when session is created and when is destroyed. So this interface have only two methods:
  • void sessionCreated(HttpSessionEvent event)
  • void sessionDestroyed(HttpSessionEvent event)
First method is called when session is created and second one before session is destroyed. Both methods have one parameter of type HttpSessionEvent. This event class have only one method which retriev HttpSession object.
  • HttpSession getSession()
HttpSessionActivationListener is interface which should be implemented by attribute classes. Classes which implements this interfaces will be informed by container about changing session state from passive to active and from active to passive, so there is no need to register this event with in application descriptor. And with this interface we get two new method:
  • void sessionDidActivate(HttpSessionEvent event), called when session has just activated.
  • void sessionWillPassivate(HttpSessionEvent event), called before session is passivated.
With implementing this interface we can make some additional step during object serialization and deserialization. 

HttpSessionAttributeListener  is interface which allow us to interact with events related to the changes of session's attributes. This interface define three methods:
  • void attributeAdded(HttpSessionBindingEvent event)
  • void attributeRemoved(HttpSessionBindingEvent event)
  • void attributeReplaced(HttpSessionBindingEvent event)
This method are called by container when attribute is added, removed or when its value is changed.
All method takes parameter of type HttpSessionBindingEvent which extend HttpSessionEvent and provide additional methods:
  • String getName(), return name of attribute which is changing.
  • Object getValue(), retrieve attribute value depending on performed action it can retriev new or old value.
HttpSessionBindingListener is a last listener defined in servlet api, and it is implemented by class which will be used as session attribute. Its purpose is to provide mechanism for informing object that it is being bound or unbound from session. This interface provide two methods:
  • void valueBound(HttpSessionBindingEvent event)
  • void valueUnbound(HttpSessionBindingEvent event)
Registering lisinter

Most of listener are defined on application level so they need to be defined by application descriptor. There is code snap from web.xml used for defining listener:
<lisitener>
     <description>This is a session attribute listener</description>
     <display-name>Session Attribute Listener<display-name>
     <listener-class>ba.codecentric.scwd.SessionAttributeListenerExample</listener-class>
</listener>
Only required element for defining listener is listener-class element.
Classes which implement HttpSessionActivationListener and HttpSessionBindingListener should not be defined in application descriptor because they are attribute level listener and method defined by this interfaces will be automatically called when some of this event occurred.

Comments

Popular posts from this blog

Checking file's "magic numbers"

Few days ago I had very interesting task. Our customer required that we perform checking of so called file's "magic numbers" to determinate does uploaded file correspond to it's extension.  We are already allowed only to upload files with some predefined extensions (PDF, DOC ...). But this can not prevent some evil user to update an exe file after renaming it to PDF or DOC. So first of all I will explain what are "magic numbers", and then I will show how we handle them.

Simple Workflow Engine With Spring

Few months ago, during working on one of the company project, we had need to developed  REST services which is used for sending an email depending on data sent by client application. During developing this service we decide to create simple workflow engine which will be charged for sending an email, but also this engine can be used for any kind of simple flows. In this article i will explain step by step how you can implement your simple workflow engine which can handle sequence flow.

Running Spring Boot Web App on the Random Port from Port Range

By default the spring boot web application is listening on the port 8080 for the incoming connection. This behavior can be changed by providing server.port property value during starting of the application or as part of the application.properties or through the code by implementing EmbeddedServletContainerCustomizer. But it would be even better if we could specified a range of the ports which can be used for the starting the application. It would be great if I could specify a property like server.portRange=8100..8200 to define a list of the port on which I want to start my service. In this blog post I will describe how this can be done.