Thursday, January 06, 2011

ServletContextListener: reading init parameters

Previously, I showed you how to schedule an ongoing task with servlets.

Recently, I needed a way to set the location of a configurable properties file for my web application. This location was to be used by each Servlet/JSP in my web application. You could add an init-param to each servlet declaration, like it is explained here. But why do this if each servlet is going to have the same value?

The better choice is to declare this parameter once and have it read when the web application is loaded by the servlet engine.

To do this, you need to once again implement the interface for ServletContextListener,

public class MyServletContextListener
   implements javax.servlet.ServletContextListener
This interface requires you to provide an implemention for
  • public void contextDestroyed(ServletContextEvent sce), and
  • public void contextInitialized(ServletContextEvent sce)
Before we get to the implementation for our listener, let's add a context parameter to our web application. This is the 'global' variable our servlets and JSP pages are interested in!
If you open web.xml and add something like the following as a direct child element of the <web-app> element,

<context-param>   
   <param-name>some parameter</param-name>
   <param-value>some parameter value</param-value>
</context-param>

And while we have the web.xml open, we will declare our listener (right below our <context-param> declaration):

<listener>    
  <listener-class>
your.package.path.MyServletContextListener  </listener-class>  
</listener>

Having declared our listener and a context parameter, our contextInitialized() will look something like:

public void contextInitialized(ServletContextEvent sce) {
  ServletContext c = sce.getServletContext();
  if (c != null) {
    if (c.getInitParameter( "some paramter") != null) {      
      c.setAttribute(         
       "some parameter",
        c.getInitParameter( "some parameter")
      );    
    }  
  }
}
When the servlet container unloads our web application, we need to clean up after ourselves (not 100% that this is necessary, but it is still a good practice):

public void contextDestroyed(ServletContextEvent sce) {
  ServletContext c = sce.getServletContext();
  if (c.getAttribute("some parameter") != null) {
     c.removeAttribute( "some parameter");
  }
}

Now, these attributes are available for each of our individual servlets by calling getServletContext().getAttribute("some parameter").

Nothing to it!