The org.apache.struts.config
package was added to Struts 1.1. The framework uses JavaBeans at
runtime to hold the configuration information it reads from the
Struts configuration files. Figure 4-4 shows the
main classes from the config
package.
Each class in the config
package holds information
from a specific section of the configuration file. After the
configuration file has been validated and parsed, the Struts
framework uses instances of these beans to represent in-memory
versions of the information that has been declared in the
configuration file. These classes act as runtime containers of the
configuration information and are used by the framework components as
needed.
The
org.apache.struts.config.ConfigRuleSet
class shown in Figure 4-4 has a slightly different,
but related, job—it contains the set of rules that are required
to parse a Struts configuration file. Its job is to construct
instances of the configuration JavaBeans mentioned in the previous
paragraph when the application is started.
The
org.apache.struts.config.ApplicationConfig
class deserves a special introduction, as it plays a very important
role in the framework. As Figure 4-4 indicates, it
is central to the entire config
package and holds
onto the configuration information that describes an entire Struts
application. If multiple subapplications are being used, there is one
ApplicationConfig
object for each subapplication.
The ApplicationConfig
class will surface
throughout the remainder of our discussion of the framework.
As the web application’s DTD is used to validate the web.xml file, the Struts DTD is used to validate the Struts configuration file.
Tip
A complete struts-config.xfile file is shown later, in Example 4-5. It may help to refer to that example following the discussion of these elements.
The following Struts DTD declaration indicates that the
struts-config
element is the root element for the
XML file and that it has eight child elements:
<!ELEMENT struts-config (data-sources?, form-beans?, global-exceptions?, global- forwards?, action-mappings?, controller?, message-resources*, plug-in*) >
The data-sources
element allows you to set up a
rudimentary data source that you can use from within the Struts
framework. A data source acts as a factory[7] for database connections and provides a single point of
control. Many data source implementations use a connection-pooling
mechanism to improve performance and scalability.
Many vendors provide their own implementations of data source
objects. The Java language provides the
javax.sql.DataSource
interface, which all implementations must implement. Most application
servers and some web containers provide built-in data source
components. All of the major database vendors also provide data
source implementations.
The data-sources
element can contain zero or more
data-source
elements:
<!ELEMENT data-sources (data-source*)>
The data-source
element allows for multiple
set-property
elements to be specified:
<!ELEMENT data-source (set-property*)>
The set-property
element allows you to configure
properties that are specific to your data source implementation.
Note
Throughout the discussion of the Struts configuration elements in the
rest of this chapter, you will notice a child element called
set-property
in many of the major elements of the
configuration file. The
set-property
element specifies the name and value of
an additional JavaBeans configuration property whose setter method
will be called on the object that represents the surrounding element.
This element is especially useful for passing additional property
information to an extended implementation class. The
set-property
element is optional, and you will use
it only if you need to pass additional properties to a configuration
class.
The set-property
element defines three attributes,
including the id
attribute, which is seldom used.
The property
attribute is the name of the
JavaBeans property whose setter method will be called. The
value
attribute is a string representing the value
that will be passed to the setter method after proper conversion.
This section provides an example of using the
set-property
element. The same format is
replicated wherever the set-property
element is
declared.
The attributes for the data-source
element are
listed in Table 4-3.
Table 4-3. Attributes of the data-source element
Name |
Description |
---|---|
|
Not currently used. |
|
The implementation class of the configuration bean that will hold the
data source information. If specified, it must be a descendant of
|
|
The servlet context attribute under which this data source will be
stored. This attribute is optional; the default value is
|
|
The fully qualified Java class name of the data source implementation
class. The class represented by this value must implement
|
Warning
The
GenericDataSource
class included with the Struts framework has been deprecated in favor
of the
Database Connection Pool (DBCP)
project from Jakarta or an implementation from your container.
The following code illustrates how to configure a data source within the Struts configuration file:
<data-sources> <data-source> <set-property property="autoCommit" value="true"/> <set-property property="description" value="MySql Data Source"/> <set-property property="driverClass" value="com.caucho.jdbc.mysql.Driver"/> <set-property property="maxCount" value="10"/> <set-property property="minCount" value="2"/> <set-property property="user" value="admin"/> <set-property property="password" value="admin"/> <set-property property="url" value="jdbc:mysql-caucho://localhost:3306/storefront"/> </data-source> </data-sources>
This code illustrates a data-source
element
configured to connect to a MySQL database using a JDBC driver from
Caucho Technology, the developers of the Resin™
servlet/EJB container.
You can specify multiple data sources within the configuration file, assign each one a unique key, and access a particular data source in the framework by its key. This gives you the ability to access multiple databases if necessary.
Although the default data source functionality provided by the framework does work, your application may require a more robust data source implementation. There are several other popular data source implementations you can use. Table 4-4 lists a few of the more popular alternative implementations.
The form-beans
element allows you to configure
multiple ActionForm
classes that are used by the
views. Within the form-beans
section, you can
configure zero or more form-bean
child elements.
Each form-bean
element also has several child
elements.
<!ELEMENT form-bean (icon?, display-name?, description?, set-property*, form- property*) >
Each form-bean
element also has four attributes
that you can specify. Table 4-5 lists the
attributes.
Table 4-5. Attributes of the form-bean element
Name |
Description |
---|---|
|
If you don’t want to use the standard configuration
bean |
|
If the class identified by the |
|
A unique identifier for this bean, which is used to reference it throughout the framework. This value is required and must be unique within a subapplication. |
|
The fully qualified name of a Java class that extends the Struts
|
Warning
Be careful when configuring the value for the type
attribute. It must be the fully qualified name of the
ActionForm
implementation class. If you misspell
the name, it can be very hard to debug this problem.
As mentioned in Chapter 3, a
form bean is
a JavaBeans class that extends the
org.apache.struts.action.ActionForm
class. The
following code shows how the form-beans
element
can be configured in the Struts configuration file:
<struts-config> <form-beans> <form-bean name="loginForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="username" type="java.lang.String"/> <form-property name="password" type="java.lang.String"/> </form-bean> <form-bean name="shoppingCartForm" type="com.oreilly.struts.order.ShoppingCartForm"/> </form-beans> </struts-config>
One of the form-bean
elements in this code uses a
feature new in Struts 1.1, called dynamic action
forms
. Dynamic action forms were discussed
briefly in Chapter 3 and will be discussed in
detail in Chapter 7.
You can pass one or more dynamic properties to an instance of the
org.apache.struts.action.DynaActionForm
class using the form-property
element. It is
supported only when the type
attribute of the
surrounding form-bean
element is
org.apache.struts.action.DynaActionForm
, or a
descendant class.
Each form-property
element also has four
attributes that you can specify. Table 4-6 lists
the attributes allowed in the
form-property
element.
Table 4-6. Attributes of the form-property element
Name |
Description |
---|---|
|
If you don’t want to use the standard configuration
bean |
|
A string representation of the initial value for this property. If not specified, primitives will be initialized to zero and objects to null. This attribute is not required. |
|
The JavaBeans property name of the property being described by this element. This attribute is required. |
|
The fully qualified Java class name of the implementation class of this bean property, optionally followed by “[ ]” to indicate that this property is indexed. This attribute is required. |
The following form-bean
fragment illustrates the use of the
form-property
element:
<form-bean name="checkoutForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="firstName" type="java.lang.String"/> <form-property name="lastName" type="java.lang.String"/> <form-property name="age" type="java.lang.Integer" initial="18"/> </form-bean>
The global-exceptions
section allows you to
configure exception handlers declaratively. The
global-exceptions
element can contain zero or more
exception
elements:
<!ELEMENT global-exceptions (exception*)>
Later in this chapter, when action mappings are discussed, you will
see that the exception
element also can be
specified in the action
element. If an
exception
element is configured for the same type
of exception both in the global-exceptions
element
and in the action
element, the
action
level will take precedence. If no
exception
element mapping is found at the
action
level, the framework will look for
exception mappings defined for the exception’s
parent class. Eventually, if a handler is not found, a
ServletException
or IOException
will be thrown, depending on the type of the original exception.
Chapter 10 deals with both declarative and
programmatic exception handling in detail. This section illustrates
how to configure declarative exception handling for your
applications.
The exception
element describes a mapping between
a Java exception that may occur during processing of a request and an
instance of
org.apache.struts.action.ExceptionHandler
that is
responsible for dealing with the thrown exception. The declaration of
the exception
element illustrates that it also has
several child elements:
<!ELEMENT exception (icon? display-name? description? set-property*)>
Probably more important than the child elements are the attributes
that can be specified in the exception
element.
The attributes are listed in Table 4-7.
Table 4-7. Attributes of the exception element
Name |
Description |
---|---|
|
The implementation class of the configuration bean that will hold the
exception information. If specified, it must be a descendant of
|
|
The fully qualified Java class name of the exception handler that
will process the exception. If no value is specified, the default
class |
|
A message key that is specified in the resource bundle for this
subapplication. This value is used by the
|
|
The application-relative path of the resource to forward to if this
exception occurs. This attribute is optional; the framework will
default to the |
|
The identifier of the scope level where the
|
|
The fully qualified Java class name of the exception that is to be handled. This attribute is required because it identifies the exception, which can’t be assumed by the framework. |
|
The |
The following is an example of a global-exceptions
element:
<global-exceptions> <exception key="global.error.invalidlogin" path="/security/signin.jsp" scope="request" type="com.oreilly.struts.framework.exceptions.InvalidLoginException"/> </global-exceptions>
Every action that is executed finishes by forwarding or redirecting
to a view. This view is a JSP page or static HTML page, but might be
another type of resource. Instead of referring to the view directly,
the Struts framework uses the concept of a forward to associate a
logical name with the resource. So, instead of referring to
login.jsp directly, a Struts application may
refer to this resource as the login
forward, for
example.
The
global-forwards
section allows you to configure
forwards that can be used by all actions within an application. The
global-forwards
section consists of zero or more
forward
elements:
<!ELEMENT global-forwards (forward*)>
The forward
element maps a logical name to an
application-relative URI. The application can then perform a forward
or redirect, using the logical name rather than the literal URI. This
helps to decouple the controller and model logic from the view. The
forward
element can be defined in both the
global-forwards
and action
elements. If a forward with the same name is defined in both places,
the action
level will take precedence.
The declaration of the
forward
element illustrates that it also has
several child elements:
<!ELEMENT forward(icon?, display-name?, description, set-property*)>
As with the exception
element, the attributes
probably are more interesting than the child elements. The attributes
for the forward
element are shown in Table 4-8.
Table 4-8. Attributes of the forward element
Name |
Description |
---|---|
|
The extension class of the configuration bean that will hold the
forward information. The default class is
|
|
Set to |
|
A unique value that is used to reference this forward in the application. This attribute is required. |
|
An application-relative (if the |
|
A Boolean value that determines whether the
|
The following is an example of a global-forwards
element from the Storefront application:
<global-forwards> <forward name="Login" path="/security/signin.jsp" redirect="true"/> <forward name="SystemFailure" path="/common/systemerror.jsp"/> <forward name="SessionTimeOut" path="/common/sessiontimeout.jsp" redirect="true"/> <forward name="Welcome" path="viewsignin"/> </global-forwards>
The
org.apache.struts.action.ActionForward
class is used to hold the information configured in the
controller
element (discussed later). The
ActionForward
class now extends
org.apache.struts.config.ForwardConfig
for backward compatibility.
The
action-mappings
element contains a set of zero or more
action
elements for a Struts application:
<!ELEMENT action-mappings (action*)>
The action
element describes a mapping from a
specific request path to a corresponding Action
class. The controller selects a particular mapping by matching the
URI path in the request with the path
attribute in
one of the action
elements. The
action
element contains the following child
elements:
<!ELEMENT action (icon?, display-name?, description, set-property*, exception*, forward*)>
Two child elements should stand out in the list of children for the
action
element, because you’ve
already seen them earlier in this chapter:
exception
and
forward
.
We talked about the exception
element when we
discussed the global-exceptions
element. We
mentioned then that exception
elements could be
defined at the global or at the action level. The
exception
elements defined within the
action
element take precedence over any of the
same type defined at the global level. The syntax and attributes are
the same, regardless of where they are defined.
We introduced the forward
element when we
discussed the global-forwards
element. As with
exception
elements, a forward
element can be defined both at the global level and at the action
level. The action level takes precedence if the same forward is
defined in both locations. The action
element
contains quite a few attributes, shown in Table 4-9.
Table 4-9. Attributes of the action element
Name |
Description |
---|---|
|
The name of the request- or session-scope attribute under which the
form bean for this action can be accessed. A value is allowed here
only if there is a form bean specified in the |
|
The implementation class of the configuration bean that will hold the
action information. The
|
|
The application-relative path to a servlet or JSP resource that will
be forwarded to, instead of instantiating and calling the
|
|
The application-relative path to a servlet or JSP resource that will
be included with the response, instead of instantiating and calling
the |
|
The application-relative path to the input form to which control
should be returned if a validation error is encountered. Required if
the |
|
The name of the form bean associated with this action. This value
must be the |
|
The application-relative path to the submitted request, starting with
a “/” character and without the
filename extension if extension mapping is used. In other words, this
is the name of the action—for example,
|
|
A general-purpose configuration parameter that can be used to pass
extra information to the action instance selected by this action
mapping. The core framework does not use this value. If you provide a
value here, you can obtain it in your |
|
Used to match request parameter names to form bean property names.
For example, if all of the properties in a form bean begin with
“pre_”, you can set the
|
|
A comma-delimited list of security role names allowed to invoke this
|
|
Used to identify the scope in which the form bean is
placed—either |
|
Used to match request parameter names to form bean property names.
For example, if all of the properties in a form bean end with
“_foo”, you can set the
|
|
A fully qualified Java class name that extends the
|
|
A Boolean value indicating whether this action should be configured
as the default for this application. If this attribute is set to
|
|
A Boolean value indicating whether the |
The following is an example of the
“signin” action
element from the Storefront application:
<action path="/signin" type="com.oreilly.struts.storefront.security.LoginAction" scope="request" name="loginForm" validate="true" input="/security/signin.jsp"> <forward name="Success" path="/index.jsp" redirect="true"/> <forward name="Failure" path="/security/signin.jsp" redirect="true"/> </action>
The controller
element is new to Struts 1.1. Prior to
Version 1.1, the ActionServlet
contained the
controller functionality, and you had to extend that class to
override the functionality. In Version 1.1, however, Struts has moved
most of the controller functionality to the
RequestProcessor
class. The
ActionServlet
still receives the requests, but it
delegates the request handling to an instance of the
RequestProcessor
. This allows you to declaratively
assign the processor class and modify its functionality.
If you’re familiar with Version 1.0,
you’ll notice that many of the parameters that were
configured in the web.xml file for the
controller servlet now are configured using the
controller
element. Because the controller and its
attributes are defined in the struts-config.xml
file, you can define a separate controller
element
for each subapplication. The controller
element
has a single child element:
<!ELEMENT controller (set-property*)>
The controller
element can contain zero or more
set-property
elements and many different
attributes. The attributes are shown in Table 4-10.
Table 4-10. Attributes of the controller element
Name |
Description |
---|---|
|
The size of the input buffer used when processing file uploads. This
attribute is optional; the default value is |
|
The implementation class of the configuration bean that will hold the
controller information. If specified, it must be a descendant of
|
|
The default content type and optional character encoding that gets
set for each response. This attribute is not required; the default
value is |
|
The debugging level for this application. The value is used
throughout the framework to determine how verbose the logging
information should be for events that take place internally. The
larger the value, the more verbose the logging is. This attribute is
not required; the default value is |
|
A replacement pattern defining how the
If not specified, the default |
|
Set to |
|
A Boolean value indicating whether the user’s
preferred locale is stored in the user’s session if
not already present. This attribute is not required; the default
value is |
|
The maximum size (in bytes) of a file to be accepted as a file
upload. This value can be expressed as a number followed by
“K”,
“M”, or
“G” (interpreted to mean kilobytes,
megabytes, or gigabytes, respectively). This attribute is not
required; the default value is |
|
The fully qualified Java class name of the multipart request-handler
class to be used. This is used when uploading files from a
user’s local filesystem to the server. This
attribute is not required; the default value is the
|
|
A Boolean value indicating whether the framework should set
|
|
A replacement pattern defining how the
If not specified, the default |
|
The fully qualified Java class name of the request-processor class to
be used to process requests. The value specified here should be a
descendant of
|
|
Specifies the temporary working directory that is used when processing file uploads. This attribute is not required; the servlet container will assign a default value for each web application. |
The
org.apache.struts.config.ControllerConfig
class is used to represent the information configured in the
controller
element in memory. The following
fragment shows an example of how to configure the
controller
element:
<controller contentType="text/html;charset=UTF-8" debug="3" locale="true" nocache="true" processorClass="com.oreilly.struts.framework.CustomRequestProcessor"/>
The
message-resources
element specifies characteristics of
the message resource bundles that contain the localized messages for
an application. Each Struts configuration file can define one or more
message resource bundles; therefore, each subapplication can define
its own bundles. The message-resources
element
contains only a set-property
element:
<!ELEMENT message-resources (set-property*)>
Table 4-11 lists the attributes supported by the
message-resources
element.
Table 4-11. Attributes of the message-resources element
Name |
Description |
---|---|
|
The implementation class of the configuration bean that will hold the
|
|
The fully qualified Java class name of the
|
|
The servlet context attribute with which this message resource bundle
will be stored. This attribute is optional. The default value is
specified by the string constant
|
|
A Boolean value indicating how the
|
|
The base name of the resource bundle. For example, if the name of
your resource bundle is
|
The following example shows how to configure multiple
message-resources
elements for a single
application. Notice that the second element had to specify the
key
attribute, because only one can be stored with
the default key:
<message-resources null="false" parameter="StorefrontMessageResources"/> <message-resources key="IMAGE_RESOURCE_KEY" null="false" parameter="StorefrontImageResources"/>
The concept of a
plug-in
was added in Struts 1.1. This powerful feature allows your Struts
applications to discover resources dynamically at startup. For
example, if you need to create a connection to a remote system at
startup and you didn’t want to hardcode this
functionality into the application, you can use a plug-in, and the
Struts application will discover it dynamically. To use a plug-in,
create a Java class that implements the
org.apache.struts.action.PlugIn
interface and add
a plug-in
element to the configuration file. The
PlugIn
mechanism itself will be discussed further
in Chapter 9.
The plug-in
element specifies a fully qualified
class name of a general-purpose application plug-in module that
receives notification of application startup and shutdown events. An
instance of the specified class is created for each element; the
init( )
method is called when the application is
started, and the destroy( )
method is called when
the application is stopped. The class specified here must implement
the org.apache.struts.action.PlugIn
interface and
implement the init( )
and destroy( )
methods.
The plug-in
element may contain zero or more
set-property
elements, so that extra configuration
information may be passed to your PlugIn
class:
<!ELEMENT plug-in (set-property*)>
The allowed attribute for the plug-in
element is
shown in Table 4-12.
The following fragment shows two plug-in
elements
being used:
<plug-in className="com.oreilly.struts.storefront.service.StorefrontServiceFactory"/> <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> </plug-in>
Tip
The ValidatorPlugIn
shown in the second
plug-in
element shows how the Struts framework
initializes the Validator. The Validator framework is discussed in
Chapter 11.
Up to this point, you haven’t seen a complete example of a Struts configuration file. Example 4-5 provides a complete listing.
Example 4-5. A complete Struts configuration file
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config> <data-sources> <data-source> <set-property property="autoCommit" value="true"/> <set-property property="description" value="Resin Data Source"/> <set-property property="driverClass" value="com.caucho.jdbc.mysql.Driver"/> <set-property property="maxCount" value="10"/> <set-property property="minCount" value="2"/> <set-property property="user" value="admin"/> <set-property property="password" value="admin"/> <set-property property="url" value="jdbc:mysqlcaucho://localhost:3306/storefront"/> </data-source> </data-sources> <form-beans> <form-bean name="loginForm" type="com.oreilly.struts.storefront.security.LoginForm"/> <form-bean name="itemDetailForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="view" type="com.oreilly.struts.catalog.view.ItemView"/> </form-bean> </form-beans> <global-exceptions> <exception key="global.error.invalidlogin" path="/security/signin.jsp" scope="request" type="com.oreilly.struts.framework.exceptions.InvalidLoginException"/> </global-exceptions> <global-forwards> <forward name="Login" path="/security/signin.jsp" redirect="true"/> <forward name="SystemFailure" path="/common/systemerror.jsp"/> <forward name="SessionTimeOut" path="/common/sessiontimeout.jsp" redirect="true"/> </global-forwards> <action-mappings> <action path="/viewsignin" parameter="/security/signin.jsp" type="org.apache.struts.actions.ForwardAction" scope="request" name="loginForm" validate="false" input="/index.jsp"> </action> <action path="/signin" type="com.oreilly.struts.storefront.security.LoginAction" scope="request" name="loginForm" validate="true" input="/security/signin.jsp"> <forward name="Success" path="/index.jsp" redirect="true"/> <forward name="Failure" path="/security/signin.jsp" redirect="true"/> </action> <action path="/signoff" type="com.oreilly.struts.storefront.security.LogoutAction" scope="request" validate="false" input="/security/signin.jsp"> <forward name="Success" path="/index.jsp" redirect="true"/> </action> <action path="/home" parameter="/index.jsp" type="org.apache.struts.actions.ForwardAction" scope="request" validate="false"> </action> <action path="/viewcart" parameter="/order/shoppingcart.jsp" type="org.apache.struts.actions.ForwardAction" scope="request" validate="false"> </action> <action path="/cart" type="com.oreilly.struts.storefront.order.ShoppingCartActions" scope="request" input="/order/shoppingcart.jsp" validate="false" parameter="method"> <forward name="Success" path="/action/viewcart" redirect="true"/> </action> <action path="/viewitemdetail" name="itemDetailForm" input="/index.jsp" type="com.oreilly.struts.storefront.catalog.GetItemDetailAction" scope="request" validate="false"> <forward name="Success" path="/catalog/itemdetail.jsp"/> </action> <action path="/begincheckout" input="/order/shoppingcart.jsp" type="com.oreilly.struts.storefront.order.CheckoutAction" scope="request" validate="false"> <forward name="Success" path="/order/checkout.jsp"/> </action> <action path="/getorderhistory" input="/order/orderhistory.jsp" type="com.oreilly.struts.storefront.order.GetOrderHistoryAction" scope="request" validate="false"> <forward name="Success" path="/order/orderhistory.jsp"/> </action> </action-mappings> <controller contentType="text/html;charset=UTF-8" debug="3" locale="true" nocache="true" processorClass="com.oreilly.struts.framework.CustomRequestProcessor"/> <message-resources parameter="StorefrontMessageResources" null="false"/> <message-resources key="IMAGE_RESOURCE_KEY" parameter="StorefrontImageResources" null="false"/> <plug-in className="com.oreilly.struts.storefront.service.StorefrontServiceFactory"/> <plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/> </plug-in> </struts-config>
Now that you’ve seen how to configure the default application for Struts, the last step is to discuss how you include multiple application modules. With Struts 1.1, you have the ability to set up multiple Struts configuration files. Although the application modules are part of the same web application, they act independently of one another. You also can switch back and forth between subapplications if you like.
Using multiple application modules allows for better organization of the components within a web application. For example, you can assemble and configure one application module for everything that deals with catalogs and items, while another module can be organized with the configuration information for a shopping cart and ordering. Separating an application into components in this way facilitates parallel development.
The first step is to create the additional Struts configuration
files. Suppose we created a second configuration file named
struts-order-config.xml. We must
modify the web.xml file for the
application and add an additional init-param
element for the new module. This was shown earlier in the chapter,
but it’s repeated here for convenience. Example 4-6 shows the servlet instance mapping from before
with an additional init-param
for the second
Struts configuration file.
Example 4-6. A partial web.xml file that illustrates how to configure multiple subapplications
<servlet> <servlet-name>storefront</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> <init-param> <param-name>config/order</param-name> <param-value>/WEB-INF/struts-order-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
Notice that the param-name
value for the
nondefault application module in Example 4-6 begins
with config/
. All nondefault application
modules’ param-name
elements must
begin with config/
; the default
application’s param-name
element
contains the config
value alone. The part that
comes after config/
is known as the
application module prefix and is used
throughout the framework for intercepting requests and returning the
correct resources.
Tip
With the current version of the Struts framework, only extension mapping is supported when using multiple application modules. Path mapping is not yet supported.
Pay special attention to the configuration attributes available in the various Struts XML elements. Some of them, as mentioned in this chapter, have a profound effect on how an application operates in a multiapplication module environment.
To ensure that your Struts configuration file is valid, it can and
should be validated against the Struts DTD. To do this, you must
include the DOCTYPE
element at the beginning of your
Struts configuration XML file:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
In earlier versions of the framework, there were some issues with applications not being able to start up if they couldn’t get to the Jakarta site and access the DTD from there. This is no longer the case, as Struts now provides local copies of the DTDs.
Some users prefer to specify a SYSTEM DOCTYPE
tag,
rather than a PUBLIC
one. This allows you to
specify an absolute path instead of a relative one. Although this may
solve a short-term problem, it creates more long-term ones. You
can’t always guarantee the directory structure from
one target environment to another. Also, different containers act
differently when using a SYSTEM DOCTYPE
tag. You
probably are better off not using it. However, if you decide that you
need to do so, it should look something like the following:
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config SYSTEM "file:///c:/dtds/struts-config_1_1.dtd"> <struts-config> <!--The rest of the struts configuration file goes next -->
As you can see, the location of the DTD is an absolute path. If the path of the target environment is not the same, you’ll have to modify the XML file. This is why this approach is not recommended.
[7] See the discussion of the Abstract Factory pattern in the Gang of Four’s Design Patterns: Elements of Reusable Object-Oriented Software (Addison Wesley).
Get Programming Jakarta Struts now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.