Source

xwork / docs / configuration.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <title>XWork Documentation</title>
  <link type="text/css" href="main.css" rel="STYLESHEET"/>
</head>
<body>
  <div id="page-logo">
    <a href="index.html"><img src="logo.png" border="0"/></a>
  </div>
    <div class="snip-title">
	  <h1 class="snip-name">Xwork Configuration
  
  </h1>
  </div>
<div id="snip-content" class="snip-content">

 <div class="snip-attachments"></div>
 
 Xwork is configured through the use of a file named xwork.xml in the root of the classpath which conforms to the <a href="dtd.html">Xwork 1.0 DTD</a>. This file defines the action and interceptor configurations and mappings. Here's the test xwork.xml file:<p class="paragraph"/><div class="code"><pre>&#60;!DOCTYPE xwork PUBLIC
    <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork 1.0//EN"</class>
    <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;1.0.dtd"</class>
 &#62;<p class="paragraph"/>&#60;xwork&#62;
    &#60;package name=<span class="xml&#45;quote">"default"</class>&#62;
        &#60;result&#45;types&#62;
            &#60;result&#45;type name=<span class="xml&#45;quote">"chain"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.ActionChainResult"</class>/&#62;
        &#60;/result&#45;types&#62;<p class="paragraph"/>        &#60;interceptors&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"timer"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.TimerInterceptor"</class>/&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"logger"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.LoggingInterceptor"</class>/&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"chain"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.ChainingInterceptor"</class>/&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"params"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.ParametersInterceptor"</class>/&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"static&#45;params"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.StaticParametersInterceptor"</class>/&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"component"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.component.ComponentInterceptor"</class>/&#62;
            &#60;interceptor name=<span class="xml&#45;quote">"test"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.TestInterceptor"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;expectedFoo&#60;/param&#62;
            &#60;/interceptor&#62;<p class="paragraph"/>            &#60;interceptor&#45;stack name=<span class="xml&#45;quote">"defaultStack"</class>&#62;
                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"static&#45;params"</class>/&#62;
                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"params"</class>/&#62;
            &#60;/interceptor&#45;stack&#62;<p class="paragraph"/>            &#60;interceptor&#45;stack name=<span class="xml&#45;quote">"debugStack"</class>&#62;
                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"timer"</class>/&#62;
                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"logger"</class>/&#62;
            &#60;/interceptor&#45;stack&#62;
        &#60;/interceptors&#62;<p class="paragraph"/>        &#60;global&#45;results&#62;
            &#60;result name=<span class="xml&#45;quote">"login"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;login&#60;/param&#62;
            &#60;/result&#62;
        &#60;/global&#45;results&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"Foo"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;17&#60;/param&#62;
            &#60;param name=<span class="xml&#45;quote">"bar"</class>&#62;23&#60;/param&#62;
            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;Bar&#60;/param&#62;
            &#60;/result&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"debugStack"</class>/&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"defaultStack"</class>/&#62;
        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"Bar"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;17&#60;/param&#62;
            &#60;param name=<span class="xml&#45;quote">"bar"</class>&#62;23&#60;/param&#62;
        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParam"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;expectedFoo&#60;/param&#62;
            &#60;/interceptor&#45;ref&#62;
        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParamOverride"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;foo123&#60;/param&#62;
                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;foo123&#60;/param&#62;
            &#60;/interceptor&#45;ref&#62;
        &#60;/action&#62;
    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"bar"</class> extends=<span class="xml&#45;quote">"default"</class> namespace=<span class="xml&#45;quote">"/foo/bar"</class>&#62;
        &#60;interceptors&#62;
            &#60;interceptor&#45;stack name=<span class="xml&#45;quote">"barDefaultStack"</class>&#62;
                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"debugStack"</class>/&#62;
                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"defaultStack"</class>/&#62;
            &#60;/interceptor&#45;stack&#62;
        &#60;/interceptors&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"Bar"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"barDefaultStack"</class>/&#62;
        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParamInheritance"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;expectedFoo&#60;/param&#62;
            &#60;/interceptor&#45;ref&#62;
        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParamInehritanceOverride"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;foo123&#60;/param&#62;
                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;foo123&#60;/param&#62;
            &#60;/interceptor&#45;ref&#62;
        &#60;/action&#62;
    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"abstractPackage"</class> namespace=<span class="xml&#45;quote">"/abstract"</class> abstract=<span class="xml&#45;quote">"true"</class>&#62;
        &#60;action name=<span class="xml&#45;quote">"test"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>/&#62;
    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"nonAbstractPackage"</class> extends=<span class="xml&#45;quote">"abstractPackage"</class> namespace=<span class="xml&#45;quote">"/nonAbstract"</class>/&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"baz"</class> extends=<span class="xml&#45;quote">"default"</class> namespace=<span class="xml&#45;quote">"baz"</class>&#62;
        &#60;action name=<span class="xml&#45;quote">"commandTest"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;123&#60;/param&#62;
            &#60;result name=<span class="xml&#45;quote">"error"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;bar&#60;/param&#62;
            &#60;/result&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"static&#45;params"</class>/&#62;
        &#60;/action&#62;
        &#60;action name=<span class="xml&#45;quote">"myCommand"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class> method=<span class="xml&#45;quote">"commandMethod"</class>&#62;
            &#60;param name=<span class="xml&#45;quote">"bar"</class>&#62;456&#60;/param&#62;
            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;foo&#60;/param&#62;
            &#60;/result&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"logger"</class>/&#62;
        &#60;/action&#62;
    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"multipleInheritance"</class> extends=<span class="xml&#45;quote">"default,abstractPackage,bar"</class> namespace=<span class="xml&#45;quote">"multipleInheritance"</class>&#62;
        &#60;action name=<span class="xml&#45;quote">"testMultipleInheritance"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;foo&#60;/param&#62;
            &#60;/result&#62;
            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"barDefaultStack"</class>/&#62;
        &#60;/action&#62;
    &#60;/package&#62;<p class="paragraph"/>    &#60;include file=<span class="xml&#45;quote">"includeTest.xml"</class>/&#62;
&#60;/xwork&#62;</pre></div><p class="paragraph"/>Here you can see that I've implemented Rickard's ideas (see <a href="rickard.html">RickardXWorkThoughts</a>). 
<ol>
<li>Packages - All configuration settings are in a package. Result types, interceptors, and actions are all package context specific, no more global settings (unless you have a "default" package and have your other packages extend it). Result, Interceptor, and Action configurations are inherited by packages which "extend" another package, such as package "bar" above, which extends "default".</li>
<li>Interceptor stacks - Make it easier to have sets of interceptors you apply together in a certain order. These are also inherited as part of the interceptor definition inheritance. Essentially these are just name mappings to lists of interceptors instead of one Interceptor.</li>
<li>Namespaces - a new idea of mine, this allows actions to be aliased with the same name, providing they are in different namespaces. With the ServletDispatcher, this equates to the path before the action name, which will allow for J2EE declarative security. Namespaces are optional attributes of package definitions and, if excluded, defaults to "". If the action configuration is not found with the supplied namespace, the "" namespace is checked as the default namespace, which makes it work like we have now (any path works, you get the action aliased with the name).</li>
</ol>
<h3 class="heading-1">xwork.xml elements
</h3>
<h3 class="heading-1-1">Package
</h3><p class="paragraph"/>The package element has one required attribute, "name", which acts as the key for later reference to this package. The "extends" attribute is optional and allows one package to inherit the configuration of one or more previous packages including all interceptor, interceptor-stack, and action configurations. Note that the configuration file is processed sequentially down the document, so the package referenced by an "extends" should be defined above the package which extends it. The "abstract" optional attribute allows you to make a package abstract, which will allow you to extend from it without the action configurations defined in the abstract package actually being available at runtime.
<h3 class="heading-1-1">Namespace
</h3><p class="paragraph"/>The optional namespace attribute warrants its own discussion section. The namespace attribute allows you to segregate action configurations into namespaces, so that you may use the same action alias in more than one namespace with different classes, parameters, etc. This is in contrast to Webwork 1.x, where all action names and aliases were global and could not be re-used in an application. The default namespace, which is "" (an empty string) is used as a "catch-all" namespace, so if an action configuration is not found in a specified namespace, the default namespace will also be searched. This allows you to have global action configurations outside of the "extends" hierarchy, as well as to allow the previous Webwork 1.x behavior by not specifying namespaces. It is also intended that the namespace functionality can be used for security, for instance by having the path before the action name be used as the namespace by the Webwork 2.0 ServletDispatcher, thus allowing the use of J2EE declarative security on paths to be easily implemented and maintained.
<h3 class="heading-1-1">Result-Type
</h3><p class="paragraph"/>Result types define classes and map them to names to be referred in the action configuration results. This serves as a shorthand name-value pair for these classes.
<h3 class="heading-1-1">Interceptors
</h3><p class="paragraph"/>Interceptors also serve as a name-value pairing for referring to specific Interceptor classes by a shorthand name where we use interceptor-ref elements, such as in Interceptor stacks and action configurations.
<h3 class="heading-1-1">Interceptor-Stack
</h3><p class="paragraph"/>The interceptor-stack element allows you to assign a name for later referencing via interceptor-ref to an ordered list of interceptors. This allows you to create standard groups of interceptors to be used in a certain order. The interceptor stack name/value pairs are stored in the same map as the interceptor definitions, so anywhere you use an interceptor-ref to refer to an interceptor you may also refer to an interceptor stack.
<h3 class="heading-1-1">Interceptor Parameterization
</h3><p class="paragraph"/>Interceptors are instantiated and stored at the ActionConfig level, i.e. there will be one instance per action configured in xwork.xml. These Interceptor instances may be parameterized at either the declaration level, where you map an Interceptor class to a name to be referenced later, like so:<p class="paragraph"/><div class="code"><pre>&#60;interceptor name=<span class="java&#45;quote">"test"</span> class=<span class="java&#45;quote">"com.opensymphony.xwork.TestInterceptor"</span>&#62;
    &#60;param name=<span class="java&#45;quote">"foo"</span>&#62;expectedFoo&#60;/param&#62;
&#60;/interceptor&#62;</pre></div><p class="paragraph"/>or at the interceptor-ref level, either inside an interceptor-stack or in an action declaration, like so:<p class="paragraph"/><div class="code"><pre>&#60;interceptor&#45;ref name=<span class="java&#45;quote">"test"</span>&#62;
    &#60;param name=<span class="java&#45;quote">"expectedFoo"</span>&#62;expectedFoo&#60;/param&#62;
&#60;/interceptor&#45;ref&#62;</pre></div><p class="paragraph"/>Although it is allowed by the DTD, parameters applied to interceptor-refs which refer to interceptor-stack elements will NOT be applied, and will cause a warning message.
<h3 class="heading-1-1">Global-results
</h3><p class="paragraph"/>The global results allows you to define result mappings which will be used as defaults for all action configurations and will be automatically inherited by all action configurations in this package and all packages which extend this package.
<h3 class="heading-1-1">Action
</h3><p class="paragraph"/>The action element allows the mapping of names to action classes. These names are used, along with the namespace described above, to retrieve the action config from the configuration. The action may also be parameterized by using the param elements, as above, which will set parameters into the Action at execution (with the help of the StaticParametersInterceptor).<p class="paragraph"/>The action may also have one or more results mapped to string return codes, such as "success", "error", or "input", which are the default 3 return states for actions, although ANY return string may be used and mapped to a result. The result, which is mapped to a result class by the "type" attribute which refers to the result-type name defined above, may also be parameterized by using the param element.<p class="paragraph"/>There is one shortcut when defining results, as a lot of the time a result will have only one parameter (which is often a location to redirect to (when using XWork in the web sense)).<p class="paragraph"/>Here is the long form of a result with a single location parameter:<p class="paragraph"/><div class="code"><pre>&#60;result name=<span class="java&#45;quote">"test"</span>&#62;
    &#60;param name=<span class="java&#45;quote">"location"</span>&#62;foo.jsp&#60;/param&#62;
&#60;/result&#62;</pre></div><p class="paragraph"/>and this is the 'shortcut' form:<p class="paragraph"/><div class="code"><pre>&#60;result name=<span class="java&#45;quote">"test"</span>&#62;foo.jsp&#60;/result&#62;</pre></div><p class="paragraph"/>Note that this shortcut <b class="bold">only</b> works when there is a single parameter for the result and the result has defined what its default parameter is.<p class="paragraph"/>The action may also define one or more interceptor refs to either interceptors or interceptor stacks to be applied before and after the action execution (see the section on Interceptors below). The ordering of these interceptor refs determines the order in which they will be applied.
<h3 class="heading-1-1">Includes - using multiple configuration files
</h3><p class="paragraph"/>The xwork.xml configuration file may be broken up into several files, each with its own set of package declarations, by using the &#60;include&#62; element zero or more times at the bottom of your xwork.xml file, like so:<p class="paragraph"/><div class="code"><pre>&#60;include file=<span class="java&#45;quote">"includeTest.xml"</span>/&#62;</pre></div><p class="paragraph"/>These files will be processed, in order, in the same manner as the main xwork.xml, thus may have all of the same structures, including the &#60;include&#62; element. Although it is, therefore, possible to have packages in configuration files listed later in an include element extend packages defined in an earlier included file, it is not recommended. It should be considered best practice, in the case of using multiple configuration files, to declare default packages meant to be extended in the xwork.xml and to have no dependencies between sub-configuration files.
<h3 class="heading-1">Configuration Providers
</h3><p class="paragraph"/>XWork configuration is handled through classes which implement the ConfigurationProvider interface.  The default implementation is the XmlConfigurationProvider class.  You can either create a new provider by implementing the ConfigurationProvider interface or you can extend the XmlConfigurationProvider class.  The XmlConfigurationProvider class includes a protected method called getInputStream() which is called to acquire the configuration InputStream which is expected to be an XML data stream.  The default implementation looks for a file called xwork.xml in the class path but by overriding the getInputStream() method you can pull configuration data from any source.<p class="paragraph"/>Custom configuration providers must be registered with the ConfigurationManager before they will be used to load configuration data.  If no custom configuration providers are registered then the default configuration provider is used.  If any custom configuration providers are registered then the default configuration provider will no longer be used (although you could add a new instance of it yourself to include it in the list of providers which is searched).  To add a configuration provider just call the ConfigurationManager.addConfigurationProvider() method with the custom configuration provider as the argument.
  </div>
</body>
</html>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.