Wednesday, February 15, 2012

Servlet Config, Context & Listeners

Why talk about Servlets when there are JSPs…. Right ? That’s what came into mind especially when we read about how JSPs are way more easy and fun to write. But Servlet exists for a more meaningful purpose that than just churn out HTML, for instance they act as a Controller for many frameworks. But this is not about how important Servlets are, rather today we will talk about ServletConfig, ServletContext and ServletContextListeners.
ServletConfig is a helper object which we can use in our servlets to get configuration of a Servlet. The configuration can include things like Servlet name, its context (described below) and init-parameters. For example, consider the following servlet declaration in a Deployment Descriptor (DD)
So instead of hardcoding the feedback email in the servlet responsible for sending the feedback mail, we can simple configure it in the DD and the servlet can pick the value from using ServletConfig as shown below:
The container is responsible for creating a ServletConfig object per servlet and pass to it after it has been initialized so it would be good to note that we can not use this object until the init() method i.e. we cannot access these init params inside the servlet’s constructor.
ServletContext, on the other hand acts as a global helper and is not created once per servlet, rather it is created once per application (when an application is deployed) and is normally used to configure application level parameters amongst other things. A typical example would look like:
and would be accessed as
Now these params can be accessed across all the servlets and JSPs that the application deploys. There are a bunch of other useful information that you can grab from a ServletContext and all of that can be seen here.
What if I want to do some special handling when my web application is initialized (or deployed) or destroyed/removed ? The servlet spec gives you a way to hook into the lifecycle of your web application by implementing a ServletContextListener which can listen for these events and act accordingly. Following is an example that picks up the datasource configuration from DD and creates a corresponding DataSource object and save it in ServletContext so that it can be easily retrieved by any servlet wishing to perform a database operation:
The actual code of creating a DataSource object from the string is being left out as it does not serve any purpose for this example. This listener will have to be configured in the deployment descriptor so that it can listen and respond to the lifecycle events as:
There are many other types of listeners that we can write to handle different use cases viz. ServletRequestListener, ServletRequestAttributeListener, ServletContextAttributeListener to name a few but we will see them in action some other day.
With Java EE Annotations, we really don’t have to configure a servlet in DD (as shown in the examples above). They are just there to make things easy to comprehend.