Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

When an action class method completes, it returns a String. The value of the String is used to select a result element. An action mapping will often have a set of results representing different possible outcomes. A standard set of result tokens are defined by the ActionSupport base class.

Overview

Results are string constants that Actions return to indicate the status of an Action execution. A standard set of Results are defined by default: error, input, login, none and success. Developers are, of course, free to create their own Results to indicate more application specific cases. Results are mapped to defined Result Types using a name-value pair structure.

Result tags

Result tags tell WebWork what to do next after the action has been called. There are a standard set of result codes built-in to WebWork, (in the Action interface) they include:

Code Block
java
java
titlePredefined result names

String SUCCESS = "success";
String NONE    = "none";
String ERROR   = "error";
String INPUT   = "input";
String LOGIN   = "login";

You can extend these as you see fit. Most of the time you will have either SUCCESS or ERROR, with SUCCESS moving on to the next page in your application;

...


<result name="success" type="dispatcher">
    <param name="location">/thank_you.jsp</param>
</result>

Of course, applications can define other result tokens to match specific cases.

(info) Returning ActionSupport.NONE (or null) from an action class method causes the results processing to be skipped. This is useful if the action fully handles the result processing such as writing directly to the HttpServletResponse OutputStream.

Result Elements

The result element has two jobs. First, it provides a logical name. An Action can pass back a token like "success" or "error" without knowing any other implementation details. Second, the result element provides a result type. Most results simply forward to a server page or template, but other Result Types can be used to do more interesting things.

Intelligent Defaults

Each package may set a default result type to be used if none is specified in a result element. If one package extends another, the "child" package can set its own default result, or inherit one from the parent.

Code Block
titleSetting a default Result Type
<result-types>
   <result-type name="dispatcher" default="true"
                class="org.apache.struts2.dispatcher.ServletDispatcherResult" />
</result-types>

If a type attribute is not specified, the framework will use the default dispatcher type, which forwards to another web resource. If the resource is a JavaServer Page, then the container will render it, using its JSP engine.

Likewise if the name attribute is not specified, the framework will give it the name "success".

Using these intelligent defaults, the most often used result types also become the simplest.

Code Block
xml
xml
titleResult element without defaults

...and ERROR moving on to an error page, or the preceding page;

...


<result name="error" type="dispatcher">
    <param name="location">/error.jsp</param>
</result>

Results are specified in a xwork xml config file(xwork.xml) nested inside <action>. If the location param is the only param being specified in the result tag, you can simplify it as follows:

Code Block

<action name="bar" class="myPackage.barAction">
  <result name="success" type="dispatcher">
    <param name="location">foo>/ThankYou.jsp</param>
  </result>
</action>

or simplified

Code Block
xml
xml
titleA Result element using some defaults
<result>
    <param
Code Block

<action name="bar" class="myPackage.barAction">
  <result name="success" type="dispatcher">foolocation">/ThankYou.jsp</result>param>
</action>

...

result>

The param tag sets a property on the Result object. The most commonly-set property is location, which usually specifies the path to a web resources. The param attribute is another intelligent default.

Code Block
xml
xml
titleResult element using more defaults
<result>/ThankYou.jsp</result>

Mixing results with intelligent defaults with other results makes it easier to see the "critical path".

Code Block
xml
xml
titleMultiple Results
<action name="Hello">
    <result>/hello/Result.jsp</result>
    <result name="error">/hello/Error.jsp</result>
    <result name="input">/hello/Input.jsp</result>
</action>

A special 'other' result can be configured by adding a result with name="*". This result will only be selected if no result is found with a matching name.

Code Block
xml
xml
title'*' Other Result
<action name="Hello">
    <result>/hello/Result.jsp</result>
    <result name="error">/hello/Error.jsp</result>

...

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. In other words, if you have the same result specified within multiple actions, then you can define it as a global result.

global results example
Code Block

<package name="default">
....
<global-results> 
    <result name="login" type="dispatcher"> 
        <param name="location">login.jsp</param> 
    </result> 
</global-results> 
<action name="foo"  class="mypackage.fooAction">
    <result name="success" type="dispatcher">bar.jsp</result> 
</action>
<action name="submitForm"  class="mypackage.submitFormAction">
    <result name="success" type="dispatcher">submitSuccess.jsp</result> 
</action>
...
</package>

Same thing

Code Block

<package name="default">
....
<action name="foo"  class="mypackage.fooAction">
    <result name="success" type="dispatcher">barinput">/hello/Input.jsp</result> 
    <result name="login" type="dispatcher">login*">/hello/Other.jsp</result> 
</action>
<action 

(info) The name="*" is not a wildcard pattern, it is a special name that is only selected if an exact match is not found.

(warning) In most cases if an action returns an unrecognized result name this would be a programming error and should be fixed.

Multiple names

It is possible to define multiple names for the same result:

Code Block
languagexml
<action name="savesubmitForm"  class="mypackage.submitFormAction">
    <result name="success" type="dispatcher">submitSuccess<result>success.jsp</result>
    <result name="login" type="dispatcher">loginerror, input">input-form.jsp</result>  
</action>
...
</package>

...

Such functionality was added in Struts 2.5

Global Results

Most often, results are nested with the action element. But some results apply to multiple actions. In a secure application, a client might try to access a page without being authorized, and many actions may need access to a "logon" result.

If actions need to share results, a set of global results can be defined for each package. The framework will first look for a local result nested in the action. If a local match is not found, then the global results are checked.

Code Block
xml
xml
titleDefining global results
<global-results>
    <result name="error">/Error.jsp</result>
    <result name="invalid.token">/Error.jsp</result>
    <result name="login" type="redirectAction">Logon!input</result>
</global-results>

(lightbulb) For more about results, see Result Types.

Dynamic Results

A result may not be known until execution time. Consider the implementation of a state-machine-based execution flow; the next state might depend on any combination of form input elements, session attributes, user roles, moon phase, etc. In other words, determining the next action, input page, etc. may not be known at configuration time.

Result values may be retrieved from its corresponding Action implementation by using EL expressions that access the Action's properties, just like the Struts 2 tag libraries. So given the following Action fragment:

Code Block
java
java
titleFragmentAction implementation
private String nextAction;

public String getNextAction() {
    return nextAction;
}

you might define a result like this:

Code Block
xml
xml
titleFragmentAction configuration
<action name="fragment" class="FragmentAction">
    <result name="next" type="redirectAction">${nextAction}</result>
</action>

If a FragmentAction method returns "next" the actual value of that result will be whatever is in FragmentAction's nextAction property. So nextAction may be computed based on whatever state information necessary then passed at runtime to "next"'s redirectAction.

See Parameters in configuration results for an expanded discussion.

 

Returning Result Objects

Instead of configuring results and returning the name, it is possible to return a result object:

Code Block
languagejava
public Result runAction() {
	ServletDispatcherResult result = new ServletDispatcherResult();
	result.setLocation("input-form.jsp");
	return result;
}

 

 

...