This is an automated email from the ASF dual-hosted git repository.
lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/main by this push:
new f5761f8ee docs: JSON input parameter filtering & scalar-collection
authorization (Struts 7.3.0) (#316)
f5761f8ee is described below
commit f5761f8ee49c3dc22e7b16022278e5bd0b8ae54f
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Jul 25 09:25:28 2026 +0200
docs: JSON input parameter filtering & scalar-collection authorization
(Struts 7.3.0) (#316)
* docs: document JSON input parameter filtering (Struts 7.3.0)
JSON population now applies the same name/value acceptability controls
as the Parameters Interceptor (WW-4858, apache/struts#1773):
- Always-on: framework-wide accepted/excluded name patterns, param-name
max length (paramNameMaxLength, default 100), ParameterNameAware /
ParameterValueAware callbacks, @StrutsParameter authorization.
- Opt-in: acceptedValuePatterns / excludedValuePatterns and
applyPropertyFiltersToInput (reuse excludeProperties/includeProperties
on input).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* docs: clarify @StrutsParameter depth=1 on getters for primitive
collections (JSON/REST)
@StrutsParameter authorization on the JSON path exists since 7.2.0; PRs
#1773/#1784 align its logic with ParametersInterceptor. Extend the
collections example to make clear that populating a collection of simple
types element by element (mySelection[0]) — as JSON/REST payloads do —
requires @StrutsParameter(depth = 1) on the getter, not on the setter.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
---------
Co-authored-by: Claude Opus 4.8 <[email protected]>
---
.../core-developers/struts-parameter-annotation.md | 21 +++++++++++
source/plugins/json/index.md | 42 ++++++++++++++++++++++
2 files changed, 63 insertions(+)
diff --git a/source/core-developers/struts-parameter-annotation.md
b/source/core-developers/struts-parameter-annotation.md
index 1c2ac830e..33d5dfdc6 100644
--- a/source/core-developers/struts-parameter-annotation.md
+++ b/source/core-developers/struts-parameter-annotation.md
@@ -125,6 +125,27 @@ public class MyAction {
}
```
+This covers the case where the whole collection is assigned at once (name
+`mySelection`, `depth = 0`), as a checkbox list submits it.
+
+When the collection is instead populated **element by element** through indexed
+names — `mySelection[0]`, `mySelection[1]` — the annotation must be on the
+**getter** with `depth = 1`, because each element path contains one bracket.
This
+is how JSON and REST payloads bind a collection of simple types: a body such as
+`{"mySelection":["A","B"]}` populates `mySelection[0]` and `mySelection[1]`, so
+the getter must be annotated for the elements to be accepted.
+```java
+public class MyAction {
+ private List<String> mySelection;
+
+ @StrutsParameter(depth = 1)
+ public List<String> getMySelection() {
+ return mySelection;
+ }
+ // ... setter
+}
+```
+
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
diff --git a/source/plugins/json/index.md b/source/plugins/json/index.md
index cfa7cff04..9be23a5ad 100644
--- a/source/plugins/json/index.md
+++ b/source/plugins/json/index.md
@@ -590,6 +590,48 @@ annotation **per property, during deserialization** —
unauthorized fields are
never set on the target object. Annotate the action properties that may be
populated from the JSON request body.
+### Input parameter filtering
+
+Since Struts 7.3.0, populating an action from a JSON request body applies the
+same name/value acceptability controls that the
+[Parameters Interceptor](../../core-developers/parameters-interceptor.html)
+applies to ordinary HTTP request parameters. Filtering uses the same
+dotted/indexed key paths as form parameters (`address.city`, `items[0].name`),
+so the shared pattern checkers behave identically on JSON and form input.
+Population itself stays pure reflection over bean setters — no OGNL name
+evaluation is introduced on the JSON path.
+
+The following controls are **always on**:
+
+- **Excluded and accepted name patterns** — the same framework-wide
+ accepted/excluded parameter-name patterns the Parameters Interceptor uses. A
+ JSON key whose full dotted/indexed path matches an excluded pattern, or fails
+ to match any accepted pattern, is not populated.
+- **Maximum key-path length** — set with the `paramNameMaxLength` interceptor
+ param (default `100`). JSON keys whose full dotted path is longer are
rejected.
+- **`ParameterNameAware` / `ParameterValueAware`** action callbacks — honored
for
+ JSON input exactly as for form parameters.
+- **`@StrutsParameter` authorization** — see
+ [Parameter authorization](#parameter-authorization) above.
+
+The following controls are **opt-in** — disabled by default to preserve
existing
+behavior for permissive JSON apps:
+
+| Interceptor param | Default | Effect |
+|-------------------|---------|--------|
+| `acceptedValuePatterns` | *(none)* | Comma-delimited regular expressions;
when set, only JSON leaf **values** matching one of them are accepted (matching
is case-insensitive). |
+| `excludedValuePatterns` | *(none)* | Comma-delimited regular expressions;
JSON leaf **values** matching any of them are removed (matching is
case-insensitive). |
+| `applyPropertyFiltersToInput` | `false` | When `true`, the interceptor's own
`excludeProperties` / `includeProperties` patterns — otherwise used only for
serialization output — also gate which JSON keys are populated on **input**. |
+
+```xml
+<interceptor-ref name="json">
+ <param name="paramNameMaxLength">120</param>
+ <param name="acceptedValuePatterns">[\w\s.@-]+</param>
+ <param name="applyPropertyFiltersToInput">true</param>
+ <param name="excludeProperties">login.password</param>
+</interceptor-ref>
+```
+
## JSON RPC
The json plugin can be used to execute action methods from javascript and
return the output. This feature was developed