This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch asf-staging
in repository https://gitbox.apache.org/repos/asf/struts-site.git
The following commit(s) were added to refs/heads/asf-staging by this push:
new fc5cbea7d Updates stage by Jenkins
fc5cbea7d is described below
commit fc5cbea7d232a7c2ef5df2bcece32f8cf6eadcf3
Author: jenkins <[email protected]>
AuthorDate: Wed Jul 29 07:20:04 2026 +0000
Updates stage by Jenkins
---
.../core-developers/model-driven-interceptor.html | 5 +++
.../struts-parameter-annotation.html | 36 ++++++++++++++++++++++
content/plugins/rest/index.html | 6 ++++
3 files changed, 47 insertions(+)
diff --git a/content/core-developers/model-driven-interceptor.html
b/content/core-developers/model-driven-interceptor.html
index 553f79016..7af6c770a 100644
--- a/content/core-developers/model-driven-interceptor.html
+++ b/content/core-developers/model-driven-interceptor.html
@@ -175,6 +175,11 @@ if you want the parameters to be applied to the model.</p>
<p>On the page, you can address any JavaBean properties on the business object
as if they were coded directly on the Action
class. The framework pushes the Model object onto the ValueStack.</p>
+<p class="alert alert-warning">Pushing the model onto the stack also makes it
the target of parameter binding and of <code class="language-plaintext
highlighter-rouge">@StrutsParameter</code> authorization:
+the model’s members are populated from the request without requiring the
annotation, on every input channel. Shape the
+model as a request DTO holding only the fields the action intends to accept,
not as a domain or persistence entity. See
+<a href="struts-parameter-annotation.html#modeldriven-actions">StrutsParameter
Annotation</a> for the full rules.</p>
+
<p>Many developers use Spring to acquire the business object. With the
addition of a <code class="language-plaintext
highlighter-rouge">setModel</code> method, the business logic
can be injected automatically.</p>
diff --git a/content/core-developers/struts-parameter-annotation.html
b/content/core-developers/struts-parameter-annotation.html
index 8e744184e..194acbb70 100644
--- a/content/core-developers/struts-parameter-annotation.html
+++ b/content/core-developers/struts-parameter-annotation.html
@@ -156,6 +156,7 @@
<ul id="markdown-toc">
<li><a href="#where-authorization-applies"
id="markdown-toc-where-authorization-applies">Where authorization
applies</a></li>
+ <li><a href="#modeldriven-actions"
id="markdown-toc-modeldriven-actions">ModelDriven actions</a></li>
<li><a href="#usage" id="markdown-toc-usage">Usage</a></li>
<li><a href="#understanding-the-depth-parameter"
id="markdown-toc-understanding-the-depth-parameter">Understanding the <code
class="language-plaintext highlighter-rouge">depth</code> parameter</a></li>
<li><a href="#examples" id="markdown-toc-examples">Examples</a> <ul>
@@ -186,6 +187,41 @@ action chaining (opt-in via <code
class="language-plaintext highlighter-rouge">s
authorization performed during deserialization, so unauthorized fields are
never set.</li>
</ul>
+<h2 id="modeldriven-actions">ModelDriven actions</h2>
+
+<p>When an action implements <code class="language-plaintext
highlighter-rouge">ModelDriven</code> and the <a
href="model-driven-interceptor.html">Model Driven
+Interceptor</a> has pushed the model onto the value
+stack, the <strong>model</strong> — not the action — is the authorization
target, and the
+model’s members are exempt from the annotation requirement. The whole model is
+bindable, including its nested properties, whether or not any of its fields or
+accessors carry <code class="language-plaintext
highlighter-rouge">@StrutsParameter</code>.</p>
+
+<p>This follows from what the interface declares: returning an object from
+<code class="language-plaintext highlighter-rouge">getModel()</code>
designates that object as the request surface. The model has been
+the authorization target since <code class="language-plaintext
highlighter-rouge">@StrutsParameter</code> enforcement was introduced in
+Struts 7.0.0.</p>
+
+<p>The exemption holds on <strong>every</strong> input channel listed above —
request
+parameters, JSON bodies and REST bodies alike — because they all resolve the
+authorization target the same way. It is not a JSON- or REST-specific
behavior.</p>
+
+<p>The exemption is narrowly scoped. It applies only when the action itself
+implements <code class="language-plaintext
highlighter-rouge">ModelDriven</code> <em>and</em> the object being populated
is its model rather
+than the action. A root object configured elsewhere — for example the JSON
+interceptor’s <code class="language-plaintext highlighter-rouge">root</code>
expression on an action that does not implement
+<code class="language-plaintext highlighter-rouge">ModelDriven</code> — is not
exempt, and each member it binds still requires
+<code class="language-plaintext highlighter-rouge">@StrutsParameter</code>.</p>
+
+<p>The exemption lifts the annotation requirement only. The other
parameter-name
+checks — accepted and excluded name patterns, and <code
class="language-plaintext highlighter-rouge">ParameterNameAware</code> — still
+apply to a model’s parameters as they do to an action’s.</p>
+
+<p class="alert alert-warning">Because the entire model is bindable, a <code
class="language-plaintext highlighter-rouge">ModelDriven</code> model should be
a request
+DTO carrying only the fields the action intends to accept from a request, never
+a domain or persistence entity. If you need member-level control over what is
+bindable, use action properties annotated with <code class="language-plaintext
highlighter-rouge">@StrutsParameter</code> rather than
+<code class="language-plaintext highlighter-rouge">ModelDriven</code>.</p>
+
<h2 id="usage">Usage</h2>
<p>The placement of the <code class="language-plaintext
highlighter-rouge">@StrutsParameter</code> annotation is crucial and depends on
how you want to populate your action properties.</p>
diff --git a/content/plugins/rest/index.html b/content/plugins/rest/index.html
index 1c09de631..cc0336b56 100644
--- a/content/plugins/rest/index.html
+++ b/content/plugins/rest/index.html
@@ -472,6 +472,12 @@ that can be hit via the RESTful action mapper’s
interpretation of URL’s.</p>
<p>In this example, the <code class="language-plaintext
highlighter-rouge">ModelDriven</code> interface is used to ensure that only my
model, the Order object in this case, is
returned to the client, otherwise, the whole <code class="language-plaintext
highlighter-rouge">OrdersController</code> object would be serialized.</p>
+<p class="alert alert-warning"><code class="language-plaintext
highlighter-rouge">ModelDriven</code> also determines what is bindable
<em>from</em> the request body: the model is the target of <code
class="language-plaintext highlighter-rouge">@StrutsParameter</code>
+authorization, so all of <code class="language-plaintext
highlighter-rouge">Order</code> can be populated from an incoming request
without the annotation. Shape such a model as
+a request contract carrying only the fields the controller intends to accept,
rather than as a domain or persistence
+entity — see <a
href="../../core-developers/struts-parameter-annotation.html#modeldriven-actions"><code
class="language-plaintext highlighter-rouge">@StrutsParameter</code></a> for
the
+full rules.</p>
+
<p>Where’s ActionSupport? Normally, you extend ActionSupport when writing
Struts 2 actions. In these case, our controller
doesn’t do that. Why, you ask? ActionSupport provides a bunch of important
functionality to our actions, including support
for i18n and validation. All of this functionality, in the RESTful case, is
provided by the default interceptor stack