This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch docs/WW-5626-struts-parameter-depth
in repository https://gitbox.apache.org/repos/asf/struts-site.git

commit 39984cf84db87efe864a0def46ee254cb0d96854
Author: Lukasz Lenart <[email protected]>
AuthorDate: Wed Jul 1 07:03:30 2026 +0200

    WW-5626 docs: clarify @StrutsParameter depth for collections
    
    Explain how the `depth` parameter is counted (each property access or
    collection/map index is one level) and correct the collection example to
    use `depth = 2` instead of `depth = 1` — indexing into the collection is
    itself a level, so reaching an element's property needs depth 2 even for
    flat POJOs. Also note that JSON/REST payloads populating collection
    elements require the getter to be annotated, not just the setter.
    
    Reported on the user list against 7.2.1 by Markus (flyingfischer.ch).
    
    Co-Authored-By: Claude Opus 4.8 <[email protected]>
---
 .../core-developers/struts-parameter-annotation.md | 50 +++++++++++++++++++---
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/source/core-developers/struts-parameter-annotation.md 
b/source/core-developers/struts-parameter-annotation.md
index 95bb0d414..f49c147a0 100644
--- a/source/core-developers/struts-parameter-annotation.md
+++ b/source/core-developers/struts-parameter-annotation.md
@@ -34,10 +34,39 @@ The placement of the `@StrutsParameter` annotation is 
crucial and depends on how
     - Checkboxes (single or multiple values).
     - Collections and Maps, when you are populating the whole collection/map 
from the request.
 
-- **On a public getter method:** Place the annotation on a getter method when 
you want to allow populating the properties of the object returned by the 
getter. The `depth` parameter is used to control how deep the object graph can 
be populated. This is typically used for complex objects or collections of 
complex objects.
+- **On a public getter method:** Place the annotation on a getter method when 
you want to allow populating the properties of the object (or objects) returned 
by the getter. The `depth` parameter controls how deep into that object graph 
population is allowed — see [Understanding the `depth` 
parameter](#understanding-the-depth-parameter) below. This is typically used 
for complex objects or collections of complex objects.
 
 - **On a public field:** For simple types, you can place the annotation 
directly on the public field as a shorthand for a setter annotation.
 
+## Understanding the `depth` parameter
+
+When you annotate a getter, `depth` limits how far Struts may traverse the 
object
+graph reachable from that getter while applying request parameters. **Each
+navigation step counts as one level** — following a property *or* indexing 
into a
+collection or map.
+
+To find the value you need, count the segments after the annotated property in 
the
+request expression:
+
+| Request expression      | Annotated getter | Steps beyond the getter        
| Required `depth` |
+|-------------------------|------------------|--------------------------------|------------------|
+| `user.name`             | `getUser()`      | `.name`                        
| `1`              |
+| `user.address.city`     | `getUser()`      | `.address` → `.city`           
| `2`              |
+| `users[0].name`         | `getUsers()`     | `[0]` → `.name`                
| `2`              |
+
+The key point for collections and maps: **indexing into the collection is 
itself a
+level.** Reaching a property of a collection element therefore always costs 
one more
+level than reaching the same property on a plain object. This holds even when 
the
+element type is a flat POJO with only simple fields — populating 
`contents[0].title`
+still needs `depth = 2` (one level to reach the element, one more to reach its
+property), not `depth = 1`.
+
+In the annotation's own terms, `depth` is *the number of periods or brackets 
that
+may appear in the parameter name*. The default is `depth = 0`, which permits 
only
+setters and fields directly on the action class. Reaching a property of a 
returned
+object needs `depth = 1` or more; reaching a property of an object held in a
+collection or map needs `depth = 2` or more.
+
 ## Examples
 
 ### Simple field
@@ -92,21 +121,30 @@ public class MyAction {
 }
 ```
 
-#### Populating properties of objects within a collection
-
-When populating properties of objects that are already in a collection, 
annotate the getter.
+When populating properties of objects that are already in a collection, 
annotate the
+getter. Because reaching an element's property requires indexing into the 
collection
+*and then* following the property, this needs `depth = 2` (see
+[Understanding the `depth` parameter](#understanding-the-depth-parameter)).
 ```java
 public class MyAction {
     private List<User> users; // assume this is initialized in the constructor 
or elsewhere
 
-    @StrutsParameter(depth = 1)
+    @StrutsParameter(depth = 2)
     public List<User> getUsers() {
         return users;
     }
     // ...
 }
 ```
-This allows requests like `users[0].name=John`.
+This allows requests like `users[0].name=John`. Note that `depth = 2` is 
required
+even when `User` is a flat object with only simple properties — the extra 
level pays
+for indexing into the collection, not for nesting within the element.
+
+The same rule applies to JSON and REST payloads: a body such as
+`{"users":[{"name":"John"}]}` populates `users[0].name`, so the `getUsers()` 
getter
+must be annotated with `depth = 2` for the nested value to be accepted. 
Annotating
+only the setter is not enough — the JSON/REST authorization checks the getter 
when
+descending into the collection's elements.
 
 ### Complex object
 

Reply via email to