|
From: <jue...@we...> - 2003-05-16 12:56:47
|
Isabelle, Ken, everybody,
On the occasion, some examples for initializing a Spring web app, =
especially regarding Log4J.
1. Log4J for usage within a web app
In web.xml, add the following to activate Log4j with a config file =
location relative to the web app root, by default refreshing the config =
file every minute (also recognizes a context-param =
"log4jRefreshInterval", and assumes an XML file in case of a ".xml" =
extension):
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>example.root</param-value>
</context-param>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.xml</param-value>
</context-param>
<listener>
=
<listener-class>com.interface21.web.util.Log4jConfigListener</listener-cl=
ass>
</listener>
In log4j.properties, the system property with the specified =
"webAppRootKey" can be used as follows:
log4j.appender.examplefile=3Dorg.apache.log4j.FileAppender
log4j.appender.examplefile.File=3D${example.root}/WEB-INF/example.log
If you don't need a refresh check and use the default config location =
anyway (i.e. "WEB-INF\classes\log4j.properties"), you can omit the =
"log4jConfigLocation" param. Log4J performs its default initialization =
then, still recognizing the system property. Just to achieve the latter, =
WebAppRootListener would be enough, but Log4jConfigListener is fine in =
this case too (see respective javadoc).=20
If you'd like to use absolute log file paths anyway, you can omit the =
"webAppRootKey" param. You can also omit it and use the default =
"webapp.root" key in your log4j.properties - if running in an =
appropriate container like Resin that isolates system properties per web =
app. With containers like Tomcat that no not separate each web app's =
system properties, you'll need to specify a unique key per web app to =
avoid clashes.
BTW, Log4J's ${key} simply looks for a system property named "key". So =
if you like to use the webAppRootKey mechanism but also support a test =
environment with the same Log4J config file, simply call =
Log4jConfigurer.setWorkingDirectorySystemProperty(<key>) to set the =
specified system property to the current working directory.
Note: The order of the listeners is important, to initialize Log4J =
before any Spring activity.
2. Loading Spring application contexts
The following illustrates a typical setup in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/myContext.xml</param-value>
</context-param>
<listener>
=
<listener-class>com.interface21.web.context.ContextLoaderListener</listen=
er-class>
</listener>
<servlet>
<servlet-name>example</servlet-name>
=
<servlet-class>com.interface21.web.servlet.ControllerServlet</servlet-cla=
ss>
<load-on-startup>1</load-on-startup>
</servlet>
If you'd like to use a root application context, register the =
ContextLoaderListener. If you do not, you will simply have no root =
application context but just servlet-specific ones without parent. If =
you'd like to use the default root context location (i.e. =
"/WEB-INF/applicationContext.xml") anyway, you can omit the =
"contextConfigLocation" param.
A FrameworkServlet resp. ControllerServlet looks up its namespaced =
context at "/WEB-INF/<servlet-name>-servlet.xml" by default. This can be =
customized via "contextConfigLocationPrefix" and =
"customConfigLocationSuffix" context-params, e.g. prefix =
"/WEB-INF/servlets/", suffix ".xml" -> =
"/WEB-INF/servlets/<servlet-name>-servlet.xml" (see =
XmlWebApplicationContext javadoc). The "<servlet-name>-servlet" =
namespace can be customized too, but at the FrameworkServlet level: It =
can be overridden by a "namespace" init-param.
Context implementation classes can also be customized, if desired. For =
the root context, this can be achieved via a "contextClass" =
context-param (see ContextLoader javadoc). A FrameworkServlet resp. =
ControllerServlet offers a "contextClass" init-param. Note that for the =
latter, the context implementation needs an (ApplicationContext, String) =
constructor, for the parent and the namespace (see FrameworkServlet =
javadoc).
3. Keep it simple
Let's review necessary settings:
- A Spring web app doesn't need any context-params or listeners at all, =
if just using a FrameworkServlet resp. ControllerServlet with its own =
context.
- If you want a root application context, register =
ContextLoaderListener.
- If you'd like to specify a custom context config location, or =
FrameworkServlet namespace or prefix or suffix, add the respective =
context-param.
- For the web app root system property (e.g. in your Log4J config), =
register WebAppRootListener or Log4jConfigListener, and specify the =
"webAppRootKey" context-param in a non-isolating container.
- For custom Log4J initialization, register Log4jConfigListener and add =
respective context-params.
So please, let's not use context-params if not needed, i.e. if using the =
defaults anyway. This avoids cluttering web.xml.
Finally an important note: I've removed both Log4jConfigServlet and =
ContextLoaderServlet, as we require Servlet 2.3 and should thus use =
Log4jConfigListener resp. ContextLoaderListener in any case. You'll have =
to adapt your config files if you've still used those initialization =
servlets up to now, but I consider it important to clean this before a =
proper release: 1 way for 1 thing to achieve. Sorry for any =
inconvenience - in case of severe impacts regarding context loading, =
write your own initialization servlet, overriding init() with a =
ContextLoader.initContext(ServletContext) call.
Regards,
Juergen
|