blob: 433fe04c355c5cf278cd3a7464dcca85bd475852 [file] [view]
---
layout: default
title: Chaining Interceptor
parent:
title: Interceptors
url: interceptors.html
---
# Chaining Interceptor
## Description
An interceptor that copies all the properties of every object in the value stack to the currently executing object,
except for any object that implements [Unchainable](/maven/struts2-core/apidocs/org/apache/struts2/Unchainable).
A collection of optional `includes` and `excludes` may be provided to control how and which parameters are copied.
Only `includes` or `excludes` may be specified. Specifying both results in undefined behavior. See the JavaDocs
for [ReflectionProvider#copy(Object, Object, java.util.Map, java.util.Collection, java.util.Collection)](/maven/struts2-core/apidocs/org/apache/struts2/util/reflection/ReflectionProvider.html#copy(java.lang.Object, java.lang.Object, java.util.Map, java.util.Collection, java.util.Collection))
for more information.
> It is important to remember that this interceptor does nothing if there are no objects already on the stack.
> This means two things:
> 1. you can safely apply it to all your actions without any worry of adverse affects.
> 2. it is up to you to ensure an object exists in the stack prior to invoking this action. The most typical way this
> is done is through the use of the <b>chain</b> result type, which combines with this interceptor to make up the action
> chaining feature.
By default Errors, Field errors and Message aren't copied during chaining, to change the behaviour you can specify
the below three constants in struts.properties or struts.xml:
- `struts.xwork.chaining.copyErrors` - set to true to copy Action Errors
- `struts.xwork.chaining.copyFieldErrors` - set to true to copy Field Errors
- `struts.xwork.chaining.copyMessages` - set to true to copy Action Messages
### Example
```xml
<constant name="struts.xwork.chaining.copyErrors" value="true"/>
```
## Parameter Authorization
By default the Chaining Interceptor copies **all** properties of the objects on
the value stack into the target action, regardless of any `@StrutsParameter`
annotation. To restrict copying to annotated properties only, set the global
constant:
```xml
<constant name="struts.chaining.requireAnnotations" value="true"/>
```
When enabled (default is `false`):
- Only properties whose target setters carry [`@StrutsParameter`](struts-parameter-annotation.html)
are copied; rejected properties are skipped and logged at `WARN`.
- Authorization uses the same `ParameterAuthorizer` service as the
[Parameters Interceptor](parameters-interceptor.html), keeping semantics consistent.
- The behaviour is **fail-closed**: if the target action cannot be introspected,
no properties are copied.
- This is a **global** constant only — there is no per-interceptor override.
## Security Considerations
Action chaining makes the data path into the target action implicit: the target is populated
from whatever happens to be on the value stack rather than from an explicit call. Keep that in
mind when designing chained actions:
- **Do not carry authorization, trust, identity, or approval state across a chain.** Re-derive
such state from the session or your security context inside the target action, so it never
depends on what a previous action left on the stack.
- **Prefer avoiding chaining where practical.** It couples the two actions together and makes
the target's inputs harder to reason about; a shared service or an explicit redirect is
usually clearer.
- **If chaining is required, narrow what is copied.** Implement
[Unchainable](/maven/struts2-core/apidocs/org/apache/struts2/Unchainable) on objects that must
never be copied from, and use the interceptor's `includes` or `excludes` parameters to limit
the copied properties to the ones the target genuinely needs.
- **Do not expose a public setter on the target action for state that must not be settable from
outside that action.** Anything with a public setter is, by design, part of the action's
input surface.
See also [Where authorization applies](struts-parameter-annotation.html#where-authorization-applies)
for an overview of the channels that can populate an action.
## Parameters
- `excludes` (optional) - the list of parameter names to exclude from copying (all others will be included)
- `includes` (optional) - the list of parameter names to include when copying (all others will be excluded)
## Extending the Interceptor
There are no known extension points to this interceptor.
## Examples
Simple example how to chain two actions
```xml
<action name="someAction" class="com.examples.SomeAction">
<interceptor-ref name="basicStack"/>
<result name="success" type="chain">otherAction</result>
</action>
<action name="otherAction" class="com.examples.OtherAction">
<interceptor-ref name="chain"/>
<interceptor-ref name="basicStack"/>
<result name="success">good_result.ftl</result>
</action>
```
This examples chains two actions but only one property from first action is copied to another
```xml
<action name="someAction" class="com.examples.SomeAction">
<interceptor-ref name="basicStack"/>
<result name="success" type="chain">otherAction</result>
</action>
<action name="otherAction" class="com.examples.OtherAction">
<interceptor-ref name="chainStack">
<param name="chain.includes">prop1</param>
</interceptor-ref>
<result name="success">good_result.ftl</result>
</action>
```