blob: f33201ea08405d104d38f5180fec3f8d81810d65 [file] [log] [blame]
<?xml version="1.0"?>
<document url="configuration.html">
<properties>
<title>The Struts User's Guide - Configuring Applications</title>
</properties>
<body>
<section name="5. Configuring Applications" href="config_apps"/>
<section name="5.1 Overview" href="config-overview">
<p>
Before you can build an application, you need to lay a solid foundation.
There are several setup tasks you need to perform before deploying
your Struts application.
These include components in the Struts configuration file
and in the Web Application Deployment Descriptor.
</p>
</section>
<section name="5.2 The Struts configuration file" href="struts-config">
<p>
The <a href="building_controller.html#config">Building Controller
Components</a> chapter covered writing the form-bean and action-mapping
portions of the Struts configuration file.
These elements usually play an important role in the development of a
Struts application.
The other elements in Struts configuration file tend to be static:
you set them once and leave them alone.
</p>
<p>
These "static" configuration elements are:
</p>
<ul>
<li>
controller
</li>
<li>
message-resources
</li>
<li>
plug-in
</li>
<li>
data-sources
</li>
</ul>
</section>
<section name="5.2.1 Controller Configuration" href="controller_config">
<p>
The <code>&lt;controller&gt;</code> element allows you to configure
the ActionServlet.
Many of the controller parameters were previously defined by servlet
initialization parameters in your <code>web.xml</code> file but have been
moved to this section of <code>struts-config.xml</code> in order to allow
different modules in the same web application to be configured differently.
For full details on available parameters see the
<a href="http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
struts-config_1_1.dtd</a> or the list below.
</p>
<ul>
<li>
<strong>bufferSize</strong> - The size (in bytes) of the input buffer
used when processing file uploads.
[4096] (optional)
</li>
<li>
<strong>className</strong> - Classname of configuration bean.
[org.apache.struts.config.ControllerConfig] (optional)
</li>
<li>
<strong>contentType</strong> - Default content type (and optional character
encoding) to be set on each response.
May be overridden by the Action, JSP, or other resource to which
the request is forwarded.
[text/html] (optional)
</li>
<li>
<strong>forwardPattern</strong> - Replacement pattern defining how the "path"
attribute of a <code>&lt;forward&gt;</code> element is mapped to a
context-relative URL when it starts with a slash (and when the
<code>contextRelative</code> property is <code>false</code>).
This value may consist of any combination of the following:
<ul>
<li>
<em>$M</em> - Replaced by the module prefix of this module.
</li>
<li>
<em>$P</em> - Replaced by the "path" attribute of the selected
<code>&lt;forward&gt;</code> element.
</li>
<li>
<em>$$</em> - Causes a literal dollar sign to be rendered.
</li>
<li>
<em>$x</em> - (Where "x" is any character not defined above)
Silently swallowed, reserved for future use.
</li>
</ul>
If not specified, the default forwardPattern is consistent with the
previous behavior of forwards.
[$M$P] (optional)
</li>
<li>
<strong>inputForward</strong> - Set to <code>true</code> if you want the
<code>input</code> attribute of <code>&lt;action&gt;</code> elements
to be the name of a local or global <code>ActionForward</code>, which
will then be used to calculate the ultimate URL.
Set to <code>false</code> to treat the <code>input</code> parameter of
<code>&lt;action&gt;</code> elements as a module-relative path to
the resource to be used as the input form.
[false] (optional)
</li>
<li>
<strong>locale</strong> - Set to <code>true</code> if you want a
<code>Locale</code> object stored in the user's session if not already
present.
[true] (optional)
</li>
<li>
<strong>maxFileSize</strong> - The maximum size (in bytes) of a file to be
accepted as a file upload.
Can be expressed as a number followed by a "K", "M", or "G",
which are interpreted to mean kilobytes, megabytes, or gigabytes,
respectively.
[250M] (optional)
</li>
<li>
<strong>memFileSize</strong> - The maximum size (in bytes) of a file whose
contents will be retained in memory after uploading. Files larger than this
threshold will be written to some alternative storage medium, typically
a hard disk. Can be expressed as a number followed by a "K", "M", or
"G", which are interpreted to mean kilobytes, megabytes, or gigabytes,
respectively.
[256K] (optional)
</li>
<li>
<strong>multipartClass</strong> - The fully qualified Java class name of the
multipart request handler class to be used with this module.
[org.apache.struts.upload.CommonsMultipartRequestHandler] (optional)
</li>
<li>
<strong>nocache</strong> - Set to <code>true</code> if you want the controller
to add HTTP headers for defeating caching to every response from
this module.
[false] (optional)
</li>
<li>
<strong>pagePattern</strong> - Replacement pattern defining how the
<code>page</code> attribute of custom tags using it is mapped to a
context-relative URL of the corresponding resource.
This value may consist of any combination of the following:
<ul>
<li>
<em>$M</em> - Replaced by the module prefix of this module.
</li>
<li>
<em>$P</em> - Replaced by the "path" attribute of the selected
<code>&lt;forward&gt;</code> element.
</li>
<li>
<em>$$</em> - Causes a literal dollar sign to be rendered.
</li>
<li>
<em>$x</em> - (Where "x" is any character not defined above)
Silently swallowed, reserved for future use.
</li>
</ul>
If not specified, the default pagePattern is consistent with the
previous behavior of URL calculation.
[$M$P] (optional)
</li>
<li>
<strong>processorClass</strong> - The fully qualified Java class name of the
<code>RequestProcessor</code> subclass to be used with this module.
[org.apache.struts.action.RequestProcessor] (optional)
</li>
<li>
<strong>tempDir</strong> - Temporary working directory to use when processing
file uploads.
[{the directory provided by the servlet container}]
</li>
</ul>
<p>
This example uses the default values for several controller parameters.
If you only want default behavior you can omit the controller section
altogether.
</p>
<pre><code><![CDATA[
<controller
processorClass="org.apache.struts.action.RequestProcessor"
debug="0"
contentType="text/html"/>;
]]></code></pre>
</section>
<section name="5.2.2 Message Resources Configuration" href="resources_config">
<p>
Struts has built in support for internationalization (I18N).
You can define one or more <code>&lt;message-resources&gt;</code> elements
for your webapp; modules can define their own resource bundles.
Different bundles can be used simultaneously in your application, the 'key'
attribute is used to specify the desired bundle.
</p>
<ul>
<li>
<strong>className</strong> - Classname of configuration bean.
[org.apache.struts.config.MessageResourcesConfig] (optional)
</li>
<li>
<strong>factory</strong> - Classname of MessageResourcesFactory.
[org.apache.struts.util.PropertyMessageResourcesFactory] (optional)
</li>
<li>
<strong>key</strong> - ServletContext attribute key to store this bundle.
[org.apache.struts.action.MESSAGE] (optional)
</li>
<li>
<strong>null</strong> - Set to <code>false</code> to display missing resource
keys in your application like '<em>???keyname???</em>' instead of
<code>null</code>.
[true] (optional)
</li>
<li>
<strong>parameter</strong> - Name of the resource bundle. (required)
</li>
</ul>
<p>Example configuration:</p>
<pre><code><![CDATA[
<message-resources
parameter="MyWebAppResources"
null="false" />
]]></code></pre>
<p>
This would set up a message resource bundle provided in the file
<code>MyWebAppResources.properties</code> under the default key.
Missing resource keys would be displayed as '<em>???keyname???</em>'.
</p>
</section>
<section name="5.2.3 PlugIn Configuration" href="plugin_config">
<p>
Struts PlugIns are configured using the <code>&lt;plug-in&gt;</code>
element within the Struts configuration file.
This element has only one valid attribute, 'className', which is the fully
qualified name of the Java class which implements the
<code>org.apache.struts.action.PlugIn</code> interface.
</p>
<p>
For PlugIns that require configuration themselves, the nested
<code>&lt;set-property&gt;</code> element is available.
</p>
<p>
This is an example using the Tiles plugin:
</p>
<pre><code><![CDATA[
<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property
property="definitions-config"
value="/WEB-INF/tiles-defs.xml"/>
</plug-in>
]]></code></pre>
</section>
<section name="5.2.4 Data Source Configuration" href="data-source_config">
<p>
Besides the objects related to defining ActionMappings, the Struts
configuration may contain elements that create other useful objects.
</p>
<p>
The <code>&lt;data-sources></code> section can be used to specify
a collection of DataSources [javax.sql.DataSource] for the use of your
application.
Typically, a DataSource represents a connection pool to a database
or other persistent store.
As a convenience, the Struts DataSource manager can be used to
instantiate whatever standard pool your application may need.
Of course, if your persistence layer provides for its own connections,
then you do not need to specify a <code>data-sources</code> element.
</p>
<p>
Since DataSource implementations vary in what properties need to be
set, unlike other Struts configuration elements, the
<code>data-source</code> element does not pre-define a slate of
properties.
Instead, the generic <code>set-property</code> feature is used to set
whatever properties your implementation may require.
Typically, these settings would include:
</p>
<ul>
<li>
A driver class name
</li>
<li>
A url to access the driver
</li>
<li>
A description
</li>
</ul>
<p>
And other sundry properties.
</p>
<pre><code><![CDATA[
<data-source type="org.apache.commons.dbcp.BasicDataSource">
<!-- ... set-property elements ... -->
</data-source>
]]></code></pre>
<p>
In Struts 1.2.0, the GenericDataSource has been removed, and it is
recommended that you use the Commons BasicDataSource or other DataSource
implementation instead. In practice, if you need to use the DataSource
manager, you should use whatever DataSource implementation works best
with your container or database.
</p>
<p>
For examples of specifying a data-sources element and using the
DataSource with an Action, see the
<a href="../faqs/database.html">Accessing a Database HowTo</a>.
</p>
</section>
<section
name="5.3 Configuring your application for modules"
href="dd_config_modules">
<p>
Very little is required in order to start taking advantage of the Struts
application module feature.
Just go through the following steps:
</p>
<ol>
<li>
Prepare a config file for each module.
</li>
<li>
Inform the controller of your module.
</li>
<li>
Use actions to refer to your pages.
</li>
</ol>
</section>
<section name="5.3.1 Module Configuration Files" href="module_config-files">
<p>
Back in Struts 1.0, a few "boot-strap" options were placed in the web.xml
file, and the bulk of the configuration was done in a single
struts-config.xml file.
Obviously, this wasn't ideal for a team environment, since multiple users
had to share the same configuration file.
</p>
<p>
In Struts 1.1, you have two options: you can list
<a href="#dd_config_servlet">multiple struts-config files</a> as a
comma-delimited list, or you can subdivide a larger application into
modules.
</p>
<p>
With the advent of modules, a given module has its own configuration file.
This means each team (each module would presumably be developed by a
single team) has their own configuration file, and there should be a lot
less contention when trying to modify it.
</p>
</section>
<section
name="5.3.2 Informing the Controller"
href="module_config-inform_controller">
<p>
In struts 1.0, you listed your configuration file as an initialization
parameter to the action servlet in web.xml.
This is still done in 1.1, but it's augmented a little.
In order to tell the Struts machinery about your different modules, you
specify multiple config initialization parameters, with a slight twist.
You'll still use "config" to tell the action servlet about your "default"
module, however, for each additional module, you will
list an initialization parameter named "config/module", where module is
the name of your module (this gets used when determining which URIs fall
under a given module, so choose something meaningful!).
For example:
</p>
<pre><code><![CDATA[
...
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/conf/struts-default.xml</param-value>
</init-param>
<init-param>
<param-name>config/module1</param-name>
<param-value>/WEB-INF/conf/struts-module1.xml</param-value>
</init-param>
...
]]></code></pre>
<p>
This says I have two modules.
One happens to be the "default" module, which has no "/module" in it's
name, and one named "module1" (config/module1).
I've told the controller it can find their respective configurations
under /WEB-INF/conf (which is where I put all my configuration files).
Pretty simple!
</p>
<p>
(My struts-default.xml would be equivalent to what most folks call
struts-config.xml.
I just like the symmetry of having all my Struts module files being
named struts-&lt;module&gt;.xml)
</p>
<p>
If you'd like to vary where the pages for each module is stored,
see the <a href="#controller_config">forwardPattern</a> setting for the
Controller.
</p>
</section>
<section name="5.3.3 Switching Modules" href="module_config-switching">
<p>
There are two basic methods to switching from one module to another.
You can either use a forward (global or local) and specify the
contextRelative attribute with a value of true, or you can use
the built-in <code>org.apache.struts.actions.SwitchAction</code>.
</p>
<p>
Here's an example of a global forward:
</p>
<pre><code><![CDATA[
...
<struts-config>
...
<global-forwards>
<forward name="toModuleB"
contextRelative="true"
path="/moduleB/index.do"
redirect="true"/>
...
</global-forwards>
...
</struts-config>
]]></code></pre>
<p>
You could do the same thing with a local forward declared in an
ActionMapping:
</p>
<pre><code><![CDATA[
...
<struts-config>
...
<action-mappings>
...
<action ... >
<forward name="success"
contextRelative="true"
path="/moduleB/index.do"
redirect="true"/>
</action>
...
</action-mappings>
...
</struts-config>
]]></code></pre>
<p>
Finally, you could use
<code>org.apache.struts.actions.SwitchAction</code>,
like so:
</p>
<pre><code><![CDATA[
...
<action-mappings>
<action path="/toModule"
type="org.apache.struts.actions.SwitchAction"/>
...
</action-mappings>
...
]]></code></pre>
<p>
Now, to change to ModuleB, we would use a URI like this:
</p>
<pre><code>
http://localhost:8080/toModule.do?prefix=/moduleB&amp;page=/index.do
</code></pre>
<p>
If you are using the "default" module as well as "named" modules (like "/moduleB"),
you can switch back to the "default" module with a URI like this:
</p>
<pre><code>
http://localhost:8080/toModule.do?prefix=&amp;page=/index.do
</code></pre>
<p>
That's all there is to it! Happy module-switching!
</p>
</section>
<section name="5.4 The Web Application Deployment Descriptor" href="dd_config">
<p>
The final step in setting up the application is to configure the
application deployment descriptor (stored in file
<code>WEB-INF/web.xml</code>) to include all the Struts components that
are required.
Using the deployment descriptor for the example application as a guide,
we see that the following entries need to be created or modified.
</p>
</section>
<section
name="5.4.1 Configure the Action Servlet Instance"
href="dd_config_servlet">
<p>
Add an entry defining the action servlet itself, along with the
appropriate initialization parameters.
Such an entry might look like this:
</p>
<pre><code><![CDATA[
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>
/WEB-INF/struts-config.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
]]></code></pre>
<p>
The initialization parameters supported by the controller servlet are
described below.
(You can also find these details in the
<a href="../api/index.html">Javadocs</a> for the ActionServlet class.)
Square brackets describe the default values that are assumed if you do
not provide a value for that initialization parameter.
</p>
<ul>
<li>
<strong>config</strong> - Context-relative path to the XML resource
containing the configuration information for the default module.
This may also be a comma-delimited list of configuration files.
Each file is loaded in turn, and its objects are appended to the
internal data structure. [/WEB-INF/struts-config.xml].<br/>
<strong>WARNING</strong> - If you define
an object of the same name in more than one configuration file,
the last one loaded quietly wins.
</li>
<li>
<strong>config/${module}</strong> - Context-relative path to the XML
resource containing the configuration information for the application
module that will use the specified prefix (/${module}).
This can be repeated as many times as required for multiple
application modules. (Since Struts 1.1)
</li>
<li>
<strong>convertNull</strong> - Force simulation of the Struts 1.0
behavior when populating forms.
If set to true, the numeric Java wrapper class types (like
<code>java.lang.Integer</code>) will default to null (rather than 0).
(Since Struts 1.1) [false]
</li>
<li>
<strong>rulesets</strong> - Comma-delimited list of fully qualified
classnames of additional
<code>org.apache.commons.digester.RuleSet</code> instances that
should be added to the <code>Digester</code> that will be processing
<code>struts-config.xml</code> files.
By default, only the <code>RuleSet</code> for the standard
configuration elements is loaded. (Since Struts 1.1)
</li>
<li>
<strong>validating</strong> - Should we use a validating XML parser to
process the configuration file (strongly recommended)?
[true]
</li>
</ul>
<p>
The following parameters may still be used with the Struts 1.1 release
but are <strong>deprecated</strong>.
</p>
<ul>
<li>
<strong>application</strong> - Java class name of the application
resources bundle base class.
[NONE]
<em>DEPRECATED - Configure this using the "parameter" attribute
of the &lt;message-resources&gt; element.</em>
</li>
<li><strong>bufferSize</strong> - The size of the input buffer used
when processing file uploads.
[4096]
<em>DEPRECATED - Configure this using the "bufferSize" attribute
of the &lt;controller&gt; element.</em>
</li>
<li>
<strong>content</strong> - Default content type and character encoding
to be set on each response; may be overridden by a forwarded-to
servlet or JSP page.
[text/html]
<em>DEPRECATED - Configure this using the "contentType" attribute
of the &lt;controller&gt; element.</em>
</li>
<li>
<strong>debug</strong> - The debugging detail level that controls
how much information is logged for this servlet.
Accepts values 0 (off) and from 1 (least serious) through 6
(most serious). [0]
<em>DEPRECATED - Configure the logging detail level in your
underlying logging implementation.</em>
</li>
<li>
<strong>factory</strong> - The Java class name of the
<code>MessageResourcesFactory</code> used to create the application
<code>MessageResources</code> object.
[org.apache.struts.util.PropertyMessageResourcesFactory]
<em>DEPRECATED - Configure this using the "factory" attribute
of the &lt;message-resources&gt; element.</em>
</li>
<li>
<strong>formBean</strong> - The Java class name of the ActionFormBean
implementation to use
[org.apache.struts.action.ActionFormBean].
<em>DEPRECATED - Configure this using the "className" attribute
of each &lt;form-bean&gt; element.</em>
</li>
<li>
<strong>forward</strong> - The Java class name of the ActionForward
implementation to use
[org.apache.struts.action.ActionForward].
Two convenient classes you may wish to use are:
<ul>
<li>
<em>org.apache.struts.action.ForwardingActionForward</em> -
Subclass of <code>org.apache.struts.action.ActionForward</code>
that defaults the <code>redirect</code> property to
<code>false</code> (same as the ActionForward default value).
</li>
<li>
<em>org.apache.struts.action.RedirectingActionForward</em> -
Subclass of <code>org.apache.struts.action.ActionForward</code>
that defaults the <code>redirect</code> property to
<code>true</code>.
</li>
</ul>
<em>DEPRECATED - Configure this using the "className" attribute of
each &lt;forward&gt; element.</em>
</li>
<li>
<strong>locale</strong> - If set to <code>true</code>, and there is a
user session, identify and store an appropriate
<code>java.util.Locale</code> object (under the standard key
identified by <code>Globals.LOCALE_KEY</code>) in the user's session
if there is not a Locale object there already.
[true]
<em>DEPRECATED - Configure this using the "locale" attribute of
the &lt;controller&gt; element.</em>
</li>
<li>
<strong>mapping</strong> - The Java class name of the ActionMapping
implementation to use
[org.apache.struts.action.ActionMapping].
Two convenient classes you may wish to use are:
<ul>
<li>
<em>org.apache.struts.action.RequestActionMapping</em> - Subclass
of <code>org.apache.struts.action.ActionMapping</code> that
defaults the <code>scope</code> property to "request".
</li>
<li>
<em>org.apache.struts.action.SessionActionMapping</em> - Subclass
of <code>org.apache.struts.action.ActionMapping</code> that
defaults the <code>scope</code> property to "session".
(Same as the ActionMapping default value).
</li>
</ul>
<em>DEPRECATED - Configure this using the "className" attribute of
each &lt;action&gt; element, or globally for a module by using the
"type" attribute of the &lt;action-mappings&gt; element.</em>
</li>
<li>
<strong>maxFileSize</strong> - The maximum size (in bytes) of a file
to be accepted as a file upload.
Can be expressed as a number followed by a "K" "M", or "G", which are
interpreted to mean kilobytes, megabytes, or gigabytes, respectively.
[250M]
<em>DEPRECATED - Configure this using the "maxFileSize" attribute of
the &lt;controller&gt; element.</em>
</li>
<li>
<strong>multipartClass</strong> - The fully qualified name of the
MultipartRequestHandler implementation class to be used for processing
file uploads.
If set to <code>none</code>, disables Struts multipart request
handling.
[org.apache.struts.upload.CommonsMultipartRequestHandler]
<em>DEPRECATED - Configure this using the "multipartClass" attribute
of the &lt;controller&gt; element.</em>
</li>
<li>
<strong>nocache</strong> - If set to <code>true</code>, add HTTP
headers to every response intended to defeat browser caching of
any response we generate or forward to.
[false]
<em>DEPRECATED - Configure this using the "nocache" attribute of
the &lt;controller&gt; element.</em>
</li>
<li>
<strong>null</strong> - If set to <code>true</code>, set our
application resources to return <code>null</code> if an unknown
message key is used.
Otherwise, an error message including the offending message key will
be returned.
[true]
<em>DEPRECATED - Configure this using the "null" attribute of
the &lt;message-resources&gt; element.</em>
</li>
<li>
<strong>tempDir</strong> - The temporary working directory to use when
processing file uploads.
[The working directory provided to this web application as a servlet
context attribute]
<em>DEPRECATED - Configure this using the "tempDir" attribute of
the &lt;controller&gt; element.</em>
</li>
</ul>
<p>
<strong>WARNING</strong> - Struts will not
operate correctly if you define more than one
<code>&lt;servlet&gt;</code> element for a controller
servlet, or a subclass of the standard controller servlet class.
The controller servlet <strong>MUST</strong> be a web application
wide singleton.
</p>
</section>
<section
name="5.4.2 Configure the Action Servlet Mapping"
href="dd_config_mapping">
<p>
<strong>Note:</strong> The material in this section is not specific to
Struts.
The configuration of servlet mappings is defined in the Java Servlet
Specification.
This section describes the most common means of configuring a Struts
application.
</p>
<p>
There are two common approaches to defining the URLs that will
be processed by the controller servlet -- prefix matching and extension
matching.
An appropriate mapping entry for each approach will be described below.
</p>
<p>
Prefix matching means that you want all URLs that start (after the context
path part) with a particular value to be passed to this servlet.
Such an entry might look like this:
</p>
<pre><code><![CDATA[
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
]]></code></pre>
<p>
which means that a request URI to match the <code>/logon</code> path
described earlier might look like this:
</p>
<pre><code>http://www.mycompany.com/myapplication/do/logon</code></pre>
<p>
where <code>/myapplication</code> is the context path under which your
application is deployed.
</p>
<p>
Extension mapping, on the other hand, matches request URIs to the
action servlet based on the fact that the URI ends with a period
followed by a defined set of characters.
For example, the JSP processing servlet is mapped
to the <code>*.jsp</code> pattern so that it is called to process
every JSP page that is requested.
To use the <code>*.do</code> extension (which implies "do something"),
the mapping entry would look like this:
</p>
<pre><code><![CDATA[
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
]]></code></pre>
<p>
and a request URI to match the <code>/logon</code> path described
earlier might look like this:
</p>
<pre><code>http://www.mycompany.com/myapplication/logon.do</code></pre>
<p>
<strong>WARNING</strong> - Struts will not
operate correctly if you define more than one
<code>&lt;servlet-mapping&gt;</code> element for the controller
servlet.
</p>
<p>
<strong>WARNING</strong> - If you are using
the new module support in Struts 1.1, you should be aware
that <strong>only</strong> extension mapping is supported.
</p>
</section>
<section
name="5.4.3 Configure the Struts Tag Libraries"
href="dd_config_taglib">
<p>
Next, you must add an entry defining the Struts tag library.
</p>
<p>
The struts-bean taglib contains tags useful in accessing beans and their
properties, as well as defining new beans (based on these accesses)
that are accessible to the remainder of the page via scripting
variables and page scope attributes.
Convenient mechanisms to create new beans based on the value of request
cookies, headers, and parameters are also provided.
</p>
<p>
The struts-html taglib contains tags used to create struts input forms,
as well as other tags generally useful in the creation of HTML-based
user interfaces.
</p>
<p>
The struts-logic taglib contains tags that are useful in managing
conditional generation of output text,
looping over object collections for repetitive generation of output
text, and application flow management.
</p>
<p>
The struts-tiles taglib contains tags used for combining various view
components, called "tiles", into a final composite view.
</p>
<p>
The struts-nested taglib is an extension of other struts taglibs that
allows the use of nested beans.
</p>
<p>
Below is how you would define all taglibs for use within your
application.
In practice, you would only specify the taglibs that your application
uses:
</p>
<pre><code><![CDATA[
<taglib>
<taglib-uri>
/tags/struts-bean
</taglib-uri>
<taglib-location>
/WEB-INF/struts-bean.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
/tags/struts-html
</taglib-uri>
<taglib-location>
/WEB-INF/struts-html.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
/tags/struts-logic
</taglib-uri>
<taglib-location>
/WEB-INF/struts-logic.tld
</taglib-location>
</taglib>
<taglib>
<taglib-uri>
/tags/struts-tiles
</taglib-uri>
<taglib-location>
/WEB-INF/struts-tiles.tld
</taglib-location>
</taglib>
]]></code></pre>
<p>
This tells the JSP system where to find the tag library descriptor
for this library (in your application's WEB-INF directory, instead of
out on the Internet somewhere).
</p>
</section>
<section
name="5.4.3.1 Configure the Struts Tag Libraries (Servlet 2.3)"
href="dd_config_taglib_23">
<p>
<strong>Servlet 2.3 Users only:</strong> The Servlet 2.3 specification simplifies
the deployment and configuration of tag libraries.
The instructions above will work on older containers as well as 2.3
containers (Struts only requires a servlet 2.2 container);
however, if you're using a 2.3 container such as Tomcat 4.x,
you can take advantage of a simplified deployment.
</p>
<p>
All that's required to install the struts tag libraries is to copy
struts.jar into your /WEB-INF/lib directory and reference the tags in
your code like this:
</p>
<pre><code>
&lt;%@ taglib
uri="http://jakarta.apache.org/struts/tags-html"
prefix="html" %&gt;
</code></pre>
<p>
Note that you <strong>must use the full uri</strong> defined in the various struts
tlds so that the container knows where to find the tag's class files.
You don't have to alter your web.xml file or copy tlds into any
application directories.
</p>
</section>
<section
name="5.5 Add Struts Components To Your Application"
href="config_add">
<p>
To use Struts, you must copy the .tld files that you require into
your <code>WEB-INF</code> directory, and copy <code>struts.jar</code>
(and all of the <code>commons-*.jar</code> files) into your
<code>WEB-INF/lib</code> directory.
</p>
<p>
<strong>Servlet 2.3 Users:</strong> See
<a href="#dd_config_taglib_23">section 5.4.3.1</a>
for how to avoid copying the tlds into your application.
</p>
<div class="notice">
<h4 class="center">
Sidebar: Sharing JAR Files Across Web Applications
</h4>
<p>
Many servlet containers and application servers provide facilities
for sharing JAR files across multiple web applications that depend
on them. For example, Tomcat 4.1 allows you to put JAR files into
the <code>$CATALINA_HOME/shared/lib</code> or
<code>$CATALINA_HOME/common/lib</code> directories, and the classes
in those JAR files will be available in all applications, without
the need to place them in every web application's
<code>/WEB-INF/lib</code> directory. Usually, the sharing is
accomplished by creating a separate class loader that is the parent
of the class loader (created by your container) for each individual
web application.
</p>
<p>
If you have multiple Struts-based web applications, it is tempting
to consider taking advantage of this container feature, and placing
<code>struts.jar</code> and the various <code>commons-*.jar</code>
files in the shared directory, rather than in each web application.
However, there are several potential, and actual, problems with
this approach:
</p>
<ul>
<li>
Classes loaded from the shared class loader cannot see classes
in the web application's class loader, unless they are specifically
programmed to use the Thread context class loader.
For example, Struts dynamically loads your action and form bean
classes, and normally would not be able to find those classes.
Struts has been programmed to deal with this in <em>most</em>
scenarios, but it has not been thoroughly audited to ensure that
it works in <em>all</em> scenarios. The Commons libraries that
Struts uses have <strong>NOT</strong> been audited to catch all
possible scenarios where this might become a problem.
</li>
<li>
When a class is loaded from a shared class loader, static variables
used within that class become global as well. This can cause
inter-webapp conflicts when the underlying code assumes that the
statics are global only within a particular web applicaiton (which
would be true if the class was loaded from the webapp class loader).
There are many cases where Struts, and the Commons libraries it
relies on, use static variables to maintain information that is
presumed to be visible only within a single web applicaiton.
Sharing these JAR files can cause unwanted interactions, and
probably cause incorrect behavior.
</li>
<li>
When JAR files are shared like this, it is not possible to update
the JAR file versions employed by a single web application without
updating all of them. In addition, because updating a Struts version
normally requires recompilation of the applications that use it,
you will have to recompile all of your applications as well, instead
of being able to manage them independently.
</li>
</ul>
<p>
In spite of these difficulties, it is possible that sharing the
Struts and Commons JAR files <em>might</em> appear to work for you.
However, this is <strong>NOT</strong> a supported configuration.
</p>
<p>
If you file a bug report for <code>ClassNotFoundException</code> or
<code>NoClassDefFoundError</code> exceptions, or similar situations
where it appears that the wrong version of a class is being loaded,
the bug report will <strong>NOT</strong> be processed unless the
problem exists with the JAR files in their recommended location,
in the <code>/WEB-INF/lib</code> subdirectory of your webapp.
</p>
</div>
</section>
<section
name="5.6 Logging in Struts Based Applications"
href="config_logging">
<p>
In Struts 1.0, the logging functionality was fairly limited. You could
set a debugging detail level with a servlet initialization parameter, and
all log messages were written to wherever <code>ServletContext.log()</code>
output is sent by your servlet container. WIth Struts 1.1, however, all
logging messages written by Struts itself, as well as the commons librarires
that it utilizes, flow through an abstract wrapper called
<a href="http://jakarta.apache.org/commons/logging">Commons Logging</a>,
which can be used as a wrapper around any logging implementation. The most
common implementations used are simple logging to <code>System.err</code>,
the <a href="http://jakarta.apache.org/log4j/">Apache Log4J</a> package,
or the built-in logging capabilities of JDK 1.4 or later in the
<a href="http://java.sun.com/j2se/1.4/docs/api/java/util/logging/package-summary.html">
java.util.logging</a> package.
</p>
<p>
This section does not attempt to fully explain how Commons Logging is
configured and used. Instead, it focuses on pertinent details of using
Commons Logging in a Struts based environment. For complete documentation
on using Commons Logging, consult the documentation for the logging system
you are using, plus the Commons Logging
<a href="http://jakarta.apache.org/commons/logging/api/org/apache/commons/logging/package-summary.html#package_description">
Javadocs</a>.
</p>
<p>
Commons Logging provides fine-grained control over the logging messages
created by a <code>Log</code> instance. By convention, the <code>Log</code>
instances for Struts (and the Commons packages in general) are named the
fully qualified class name of the class whose messages are being logged.
Therefore, log messages created by the RequestProcessor class are, naturally
enough, directed to a logger named
<code>org.apache.struts.action.RequestProcessor</code>.
</p>
<p>
The advantage of this approach is that you can configure the level of detail
in the output you want from each class, individually. However, it would be
a burden to be required to maintain such settings for every possible class,
so the logging environment supports the notion of logging
<em>hierarchies</em> as well. If a detail level configuration for a
particular class has not been set, the logging system looks up the hierarchy
until it finds a configuration setting to use, or else uses the default
detail level if no configuration for any level of the hierarchy has been
explicitly set. In the case of our messages from <code>RequestProcessor</code>,
the logging system will look for explicit settings of the following loggers,
in this order, until it finds one.
</p>
<ul>
<li><code>org.apache.struts.action.RequestProcessor</code></li>
<li><code>org.apache.struts.action</code></li>
<li><code>org.apache.struts</code></li>
<li><code>org.apache</code></li>
<li><code>org</code></li>
<li>The default logging detail level for your log implementation.</li>
</ul>
<p>
In a similar manner, the detail level for messages from
<code>PropertyUtils</code> (from the Commons BeanUtils library) is set by
a search for configuration settings for:
</p>
<ul>
<li><code>org.apache.commons.beanutils.PropertyUtils</code></li>
<li><code>org.apache.commons.beanutils</code></li>
<li><code>org.apache.commons</code></li>
<li><code>org.apache</code></li>
<li><code>org</code></li>
<li>The default logging detail level for your log implementation.</li>
</ul>
<p>
You can seamlessly integrate logging from your own components into the same
logging implementation that Struts and the Commons libraries use, by
following the instructions in
<a href="building_controller.html#logging">Section 4.10</a>. If you do
this, you are strongly encouraged to follow the same naming convention for
loggers (based on the class name of the messages being logged) for
maximum configuration flexibility.
</p>
</section>
<section>
<p>
For more about putting it all together, see the <a href="../faqs/apps.html">
Building Applications HowTo</a>.
</p>
<p class="right">
Next: <a href="./release-notes.html">Release Notes</a>
</p>
</section>
</body>
</document>