It's not a secret anymore!
The moose likes Servlets and the fly likes Sharing ServletContext Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "Sharing ServletContext" Watch "Sharing ServletContext" New topic

Sharing ServletContext

Brian R. Wainwright
Ranch Hand

Joined: Aug 12, 2003
Posts: 92
This is a rather long-winded, general question, regarding best practice. I'm curious as to how best to share ServletContext attributes with other layers of an MVC2 application - particularly the model. I know application.getAttribute(...) can be used from within a JSP, but consider this scenario:
I have a MyService object that relays information between MyServlet and MyDataAccessObject. MyDataAccessObject runs queries and updates etc.. against a database using
Context ctx = new InitialContext();
DataSource dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/myDB");
//more stuff
The DB information is configured in Tomcat 4.1's server.xml file using <ResourceParam> tags etc...
So far, so good - nothing unusual. But what if I want that lookup key - java:comp/env/jdbc/myDB - to be part of the configuration for my application so it's not tied to a particular Servlet Container, DataBase platform, or anything else - essentially extensible? If I store it as a ServletContext attribute, how do I get that ServletContext down to the DAO, without passing it along through all the layers so it can lookup that DB info? I initially wrote a servlet class called ApplicationProperties that had an instance method:
Object getapplicationProperty(String propertyName)
ServletContext ctx = getServletContext();
return ctx.getAttribute(propertyName);
I overrode init(ServletConfig config) in this servlet and had it <load-on-startup>. I'd then be able to call:
from anywhere within my app, but I don't really like this implementation - I can't make this a Singleton class, because I can't have a private constructor (due to the Tomcat needing to create one instance of it - I think...), it seems to only work when it wants to (getServletContext() in getApplicationProperty() sometimes returns null for some strange reason) and I have a nagging feeling that there's a better way to do this. I'm thinking a java.util.Properties file, but not certain. Anyway - sorry for the long post - any ideas are helpful. Thanks!
[ August 12, 2003: Message edited by: Brian Wainwright ]
Carl Trusiak

Joined: Jun 13, 2000
Posts: 3340
One way is to create your own SystemConfiguration object. You can still make it a singleton by providing it with a ststic getInstance method. You can ad any property to it on Startup. If you are using Servlet 2.3, create a ContextListener which will execute when the WebApp starts. It can read in all your parameters and set them in the SystemConfiguration Object. If you have the Listener and the config object in the sam package, all the set methods can be default access and therefore immutable outside that package.

I Hope This Helps
Carl Trusiak, SCJP2, SCWCD
Brian R. Wainwright
Ranch Hand

Joined: Aug 12, 2003
Posts: 92
Thanks Carl. This is great info. I've done it and it works great!
Brian R. Wainwright
Ranch Hand

Joined: Aug 12, 2003
Posts: 92
Just as a general FYI to others here's what I did:
1. Created an implementation of ServletContextListener called ApplicationInitialization.
2. Created a Singelton class called ApplicationProperties that has a private member variable:
Hashtable applicationProperties = new Hashtable; and a variety of public methods for retrieving information from the Hashtable (including its Enumeration, keys, values, etc...) and 2 default accessible methods for setting stuff in the Hashtable:
a. void setApplicationProperty(Object key, Object value)
b. void setApplicationProperties(Map properties)
3. In the contextInitialized() method of ApplicationInitialization I get the desired initParameters and set the in the Hashtable. For example:
String myParam = context.getInitParameter("myParam");
ApplicationProperties props = ApplicationProperties.getInstance();
props.setApplicationProperty("myParam", myParam);
I can now access these properties from anywhere within my application simply by calling one of the accessor methods:
Object myParamValue = ApplicationProperties.getInstance().getApplicationProperty("myParam");
Thanks again Carl for the great info.
Manish Hatwalne
Ranch Hand

Joined: Sep 22, 2001
Posts: 2591

Yeah, thank you both for sharing such a great info!
- Manish
I agree. Here's the link:
subject: Sharing ServletContext
It's not a secret anymore!