![]() | ||||||||||||||||||||
application configuration files using a webbeans object
Applications often need to read, and possibly write, configuration files. An excellent way to accomplish this is to implement a custom singleton, which is easily configured and easily obtained from anywhere in the application. This implementation of the concept allows you to configure a base
directory for configuration files. An object of type
A custom singleton is a standard java-bean (see Resin-IoC). Setter methods like In this case, a single setter is provided that matches the
configuration parameter "config-files-location". The
AppConfig.java
import javax.annotations.PostConstruct;
public class AppConfig {
ConfigFilesLocation _cfl = null;
/**
* Set the base for subsequent call's to openConfigFileRead()
* and openConfigFileWrite()
*
* @param location a file path or url
*/
public void setConfigFilesLocation(String location)
throws Exception
{
_cfl = new ConfigFilesLocation();
_cfl.setLocation(location);
}
@PostConstruct
public void init()
throws Exception
{
if (_cfl == null)
throw new Exception("'config-files-location' must be set");
}
...
Configuration of the singleton is done with the <example:AppConfig> tag. The example here configures the location of the configuration files
as The EL configuration variable is used. Configuring the AppConfig singleton in resin-web.xml
<web-app xmlns="http://caucho.com/ns/resin">
<example:AppConfig xmlns:example="urn:java:example">
<config-files-location>${webApp.root}/WEB-INF/config</config-files-location>
</example:AppConfig>
</web-app>
An instance of the object is retrieved in the application using
dependency injection. In this example servlet, we'll use field-based
injection, marked by the Resin will look in the WebBeans registry for the Obtaining the AppConfig object
import javax.enterprise.inject.Current;
public class TestServlet extends GenericServlet {
@Current AppConfig _appConfig;
}
Using the AppConfig object
...
InputStream is = _appConfig.openConfigFileRead(inputFile);
...
OutputStream os = _appConfig.openConfigFileWrite(outputFile);
...
The example in this tutorial is easily modified to allow the hiding of the
configuration file behind Hiding the configuration file with getters
package example;
import java.util.*;
import java.io.*;
public class AppConfig {
private final static String DEFAULT_PROPERTIES = "example/AppConfig.properties";
private String _configFile;
private Properties _properties;
/**
* Optionally set the name of a file that provides properties that override
* the defaults. The defaults are obtained from a file in the classpath
* named 'example/AppConfig.properties'
*
* For example, the file containing default properties might be in
* WEB-INF/classes/example/AppConfig.properties,
* or if AppConfig.class is in a jar, the AppConfig.properties
* could be in the jar file alongside the AppConfig.class file.
*
* AppConfig.properties contains values placed there by the developer.
* The <config-file> is used to indicate a file that specifies properties
* that override the defaults, perhaps properties that change depending
* on the deployment environment.
*/
public void setConfigFile(String configFile)
throws Exception
{
_configFile = configFile;
}
@PostConstruct
public void init()
throws Exception
{
InputStream is = null;
if (_configFile != null) {
// the properties in _configFile override the defaults
is = new FileInputStream(_configFile);
_properties = new Properties(defaults);
_properties.load(is);
}
else {
// try to find a default configuration file in the classpath
ClassLoader loader = Thread.currentThread().getContextClassLoader();
is = loader.getResourceAsStream(DEFAULT_PROPERTIES);
if (is != null)
_properties = new Properties();
_properties.load(is);
}
else {
// throw an exception here to make the defaults required
throw new FileNotFoundException(DEFAULT_PROPERTIES);
}
}
}
public String getFoo()
{
return _properties.getProperty("foo");
}
public String getBar()
{
return _properties.getProperty("bar");
}
}
<web-app xmlns="http://caucho.com/ns/resin">
<example:AppConfig xmlns:example="urn:java:example"/>
</web-app>
or
<web-app xmlns="http://caucho.com/ns/resin">
<example:AppConfig xmlns:example="urn:java:example">
<config-file>${webApp.root}/WEB-INF/AppConfig-override.properties</config-file>
</example:AppConfig>
</web-app>
package example;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.enterprise.inject.Current;
import java.io.*;
import java.util.*;
public class TestServlet extends HttpServlet {
@Current AppConfig _appConfig;
...
String foo = _appConfig.getFoo();
String bar = _appConfig.getBar();
...
}
The availability of AppConfig to different web-apps depends upon the context that the <example:AppConfig> configuration is placed within. If the configuration is placed as a child of <web-app>, then that instance of AppConfig is available only to that web-app. WEB-INF/resin-web.xml local to web-app <web-app xmlns="http://caucho.com/ns/resin"> <example:AppConfig xmlns:example="urn:java:example"/> </web-app> If it is placed as a child of <host>, that instance of AppConfig is available to all web-apps within the host. shared host configuration in resin.conf
<resin xmlns="http://caucho.com/ns/resin">
<cluster id="">
<host id="">
<example:AppConfig xmlns:example="urn:java:example"/>
...
</host>
</cluster>
</resin>
If the <example:AppConfig> is placed as a child of <cluster>, that instance of AppConfig is available to all web-apps within all hosts within that cluster. shared cluster configuration in resin.conf
<resin xmlns="http://caucho.com/ns/resin">
<cluster id="">
<example:AppConfig xmlns:example="urn:java:example"/>
<host id="">
...
</host id="">
...
</cluster>
</resin>
In the case of <cluster> or <host>, the example.AppConfig class needs to be available in the classpath. The easiest way to accomplish that is to place a jar with that class in $RESIN_HOME/lib, or you can use an explicit <class-loader> tag.
| ||||||||||||||||||||