matt b matt b - 12 days ago 10
Java Question

Is there a way to access web.xml properties from a Java Bean?

Is there any way in the Servlet API to access properties specified in web.xml (such as initialization parameters) from within a Bean or Factory class that is not associated at all with the web container?

For example, I'm writing a Factory class, and I'd like to include some logic within the Factory to check a hierarchy of files and configuration locations to see which if any are available to determine which implementation class to instantiate - for example,


  1. a properties file in the classpath,

  2. a web.xml parameter,

  3. a system property, or

  4. some default logic if nothing else is available.



I'd like to be able to do this without injecting any reference to
ServletConfig
or anything similiar to my Factory - the code should be able to run ok outside of a Servlet Container.

This might sound a little bit uncommon, but I'd like for this component I'm working on to be able to be packaged with one of our webapps, and also be versatile enough to be packaged with some of our command-line tools without requiring a new properties file just for my component - so I was hoping to piggyback on top of other configuration files such as web.xml.

If I recall correctly, .NET has something like
Request.GetCurrentRequest()
to get a reference to the currently executing
Request
- but since this is a Java app I'm looking for something simliar that could be used to gain access to
ServletConfig
.

Answer

One way you could do this is:

public class FactoryInitialisingServletContextListener implements ServletContextListener {

    public void contextDestroyed(ServletContextEvent event) {
    }

    public void contextInitialized(ServletContextEvent event) {
        Properties properties = new Properties();
        ServletContext servletContext = event.getServletContext();
        Enumeration<?> keys = servletContext.getInitParameterNames();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            String value = servletContext.getInitParameter(key);
            properties.setProperty(key, value);
        }
        Factory.setServletContextProperties(properties);
    }
}

public class Factory {

    static Properties _servletContextProperties = new Properties();

    public static void setServletContextProperties(Properties servletContextProperties) {
        _servletContextProperties = servletContextProperties;
    }
}

And then have the following in your web.xml

<listener>
    <listener-class>com.acme.FactoryInitialisingServletContextListener<listener-class>
</listener>

If your application is running in a web container, then the listener will be invoked by the container once the context has been created. In which case, the _servletContextProperties will be replaced with any context-params specified in the web.xml.

If your application is running outside a web container, then _servletContextProperties will be empty.