This is an automated email from the ASF dual-hosted git repository.
git-site-role 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 8c8263d03 Updates stage by Jenkins
8c8263d03 is described below
commit 8c8263d03b272a9e98e354dede7f2b65c73fb898
Author: jenkins <[email protected]>
AuthorDate: Sat Oct 18 12:23:14 2025 +0000
Updates stage by Jenkins
---
content/core-developers/checkbox-interceptor.html | 48 +++++++--
.../struts-parameter-annotation.html | 120 ++++++++++++++++-----
2 files changed, 136 insertions(+), 32 deletions(-)
diff --git a/content/core-developers/checkbox-interceptor.html
b/content/core-developers/checkbox-interceptor.html
index 3c38b30d9..99b315799 100644
--- a/content/core-developers/checkbox-interceptor.html
+++ b/content/core-developers/checkbox-interceptor.html
@@ -153,25 +153,57 @@
<h1 id="checkbox-interceptor">Checkbox Interceptor</h1>
-<p>This interceptor is defined in the <code class="language-plaintext
highlighter-rouge">defaultStack</code>. It checks each form parameter submitted
to the action and if it
-finds one with a prefix of <code class="language-plaintext
highlighter-rouge">_checkbox</code> it inserts a value for a parameter whose
name is derived from the suffix
-to <code class="language-plaintext highlighter-rouge">_checkbox</code> if it
does not exist. The default value inserted is <code class="language-plaintext
highlighter-rouge">false</code> but this can be changed by setting
-the <code class="language-plaintext highlighter-rouge">uncheckedValue</code>
parameter on the interceptor.</p>
+<p>This interceptor is defined in the <code class="language-plaintext
highlighter-rouge">defaultStack</code>. It is essential for handling HTML
checkboxes, as unchecked checkboxes are not submitted as part of a form. This
interceptor ensures that a value is always present for a checkbox, so that in
the Action class, the property is not <code class="language-plaintext
highlighter-rouge">null</code>.</p>
-<p>This means that a checkbox can be accompanied by a hidden input with the
same name but a prefix of <code class="language-plaintext
highlighter-rouge">_checkbox</code> so that
-if the checkbox is not checked on the form the action will still receive a
value rather than the default HTML action
-of not providing a value for unchecked checkboxes.</p>
+<h2 id="how-it-works">How it works</h2>
+
+<p>The interceptor looks for a special hidden field in the form that is
associated with the checkbox. This hidden field must have a name that starts
with <code class="language-plaintext highlighter-rouge">__checkbox_</code>
followed by the name of the checkbox. For example, if your checkbox is named
<code class="language-plaintext highlighter-rouge">myCheckbox</code>, the
hidden field should be named <code class="language-plaintext
highlighter-rouge">__checkbox_myCheckbox</code>.</p>
+
+<p>When the form is submitted, the <code class="language-plaintext
highlighter-rouge">CheckboxInterceptor</code> does the following:</p>
+<ol>
+ <li>It iterates through the request parameters.</li>
+ <li>If it finds a parameter that starts with <code class="language-plaintext
highlighter-rouge">__checkbox_</code>, it extracts the name of the checkbox
from it (e.g., <code class="language-plaintext
highlighter-rouge">myCheckbox</code>).</li>
+ <li>It then checks if a parameter with the checkbox’s name (<code
class="language-plaintext highlighter-rouge">myCheckbox</code>) exists in the
request.</li>
+ <li>If the checkbox parameter does not exist (which means the checkbox was
unchecked), the interceptor adds a new parameter to the request with the
checkbox’s name and a value of <code class="language-plaintext
highlighter-rouge">false</code>.</li>
+ <li>Finally, it removes the <code class="language-plaintext
highlighter-rouge">__checkbox_</code> prefixed parameters from the request, so
they are not processed further.</li>
+</ol>
+
+<p>This ensures that the Action property for the checkbox will be set to <code
class="language-plaintext highlighter-rouge">false</code> instead of being
<code class="language-plaintext highlighter-rouge">null</code>.</p>
+
+<p>The <code class="language-plaintext
highlighter-rouge"><s:checkbox></code> tag from the Struts UI Tags
library automatically generates this hidden field for you.</p>
<h2 id="parameters">Parameters</h2>
<ul>
- <li><code class="language-plaintext highlighter-rouge">uncheckedValue</code>
- the default value of an unchecked box can be overridden by setting the <code
class="language-plaintext highlighter-rouge">uncheckedValue</code>
property.</li>
+ <li><code class="language-plaintext highlighter-rouge">uncheckedValue</code>
- The default value for an unchecked box is <code class="language-plaintext
highlighter-rouge">false</code>. You can override this by setting the <code
class="language-plaintext highlighter-rouge">uncheckedValue</code> property on
the interceptor.</li>
</ul>
<h2 id="extending-the-interceptor">Extending the Interceptor</h2>
<p>This interceptor does not have any known extension points.</p>
+<h2 id="checkbox-lists-usage-with-strutsparameter">Checkbox lists usage with
@StrutsParameter</h2>
+
+<p>The <code class="language-plaintext
highlighter-rouge"><s:checkboxlist></code> tag is used to render a list
of checkboxes. When using this tag, the submitted values are populated into a
<code class="language-plaintext highlighter-rouge">Collection</code> or an
array in your Action.
+When using <code class="language-plaintext
highlighter-rouge">@StrutsParameter</code> with a checkbox list, you must place
the annotation on the setter method of the collection property.</p>
+
+<h3 id="example">Example</h3>
+
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="kd">extends</span> <span class="nc">ActionSupport</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="nc">Collection</span><span
class="o"><</span><span class="nc">String</span><span class="o">></span>
<span class="n">mySelection</span><span class="o">;</span>
+
+ <span class="nd">@StrutsParameter</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">setMySelection</span><span class="o">(</span><span
class="nc">Collection</span><span class="o"><</span><span
class="nc">String</span><span class="o">></span> <span
class="n">mySelection</span><span class="o">)</span> <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span
class="na">mySelection</span> <span class="o">=</span> <span
class="n">mySelection</span><span class="o">;</span>
+ <span class="o">}</span>
+
+ <span class="nd">@StrutsParameter</span>
+ <span class="kd">public</span> <span class="nc">Collection</span><span
class="o"><</span><span class="nc">String</span><span class="o">></span>
<span class="nf">getMySelection</span><span class="o">()</span> <span
class="o">{</span>
+ <span class="k">return</span> <span class="n">mySelection</span><span
class="o">;</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</code></pre></div></div>
+
</section>
</article>
diff --git a/content/core-developers/struts-parameter-annotation.html
b/content/core-developers/struts-parameter-annotation.html
index 8fa2c0d72..4ee31a9fb 100644
--- a/content/core-developers/struts-parameter-annotation.html
+++ b/content/core-developers/struts-parameter-annotation.html
@@ -159,44 +159,116 @@
<h2 id="usage">Usage</h2>
-<p>Used to annotate public <em>getter/setter</em> methods or <em>fields</em>
on Action classes that are intended for parameter injection</p>
-
-<h2 id="parameters">Parameters</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>
<ul>
- <li><code class="language-plaintext highlighter-rouge">depth</code> controls
how deep into nested objects parameters can be set:</li>
+ <li><strong>On a public setter method:</strong> Place the annotation on a
setter method when you want to populate the property with a value from the
request. This applies to:
+ <ul>
+ <li>Simple types (String, int, boolean, etc.).</li>
+ <li>Checkboxes (single or multiple values).</li>
+ <li>Collections and Maps, when you are populating the whole
collection/map from the request.</li>
+ </ul>
+ </li>
+ <li>
+ <p><strong>On a public getter method:</strong> Place the annotation on a
getter method when you want to allow populating the properties of the object
returned by the getter. The <code class="language-plaintext
highlighter-rouge">depth</code> 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.</p>
+ </li>
+ <li><strong>On a public field:</strong> For simple types, you can place the
annotation directly on the public field as a shorthand for a setter
annotation.</li>
</ul>
<h2 id="examples">Examples</h2>
+<h3 id="simple-field">Simple field</h3>
+
+<p>Annotating the field:</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
<span class="nd">@StrutsParameter</span>
<span class="kd">public</span> <span class="nc">String</span> <span
class="n">username</span><span class="o">;</span> <span class="c1">// ✅ Can
receive request parameter</span>
+<span class="o">}</span>
+</code></pre></div></div>
+<p>Annotating the setter:</p>
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="nc">String</span> <span
class="n">username</span><span class="o">;</span>
+ <span class="nd">@StrutsParameter</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">setUsername</span><span class="o">(</span><span
class="nc">String</span> <span class="n">username</span><span
class="o">)</span> <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span
class="na">username</span> <span class="o">=</span> <span
class="n">username</span><span class="o">;</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</code></pre></div></div>
+
+<h3 id="checkbox">Checkbox</h3>
- <span class="kd">public</span> <span class="nc">String</span> <span
class="n">password</span><span class="o">;</span> <span class="c1">// ❌ Cannot
receive request parameter (not annotated)</span>
+<p>For a single checkbox, the annotation must be on the setter.</p>
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="kt">boolean</span> <span
class="n">myCheckbox</span><span class="o">;</span>
+
+ <span class="nd">@StrutsParameter</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">setMyCheckbox</span><span class="o">(</span><span
class="kt">boolean</span> <span class="n">myCheckbox</span><span
class="o">)</span> <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span
class="na">myCheckbox</span> <span class="o">=</span> <span
class="n">myCheckbox</span><span class="o">;</span>
+ <span class="o">}</span>
+ <span class="c1">// ... getter</span>
<span class="o">}</span>
</code></pre></div></div>
-<p>The <code class="language-plaintext highlighter-rouge">depth</code>
controls how deep into nested objects parameters can be set:</p>
-<ul>
- <li><code class="language-plaintext highlighter-rouge">depth = 0</code>
(default): Only sets values directly on your action
- <div class="language-plaintext highlighter-rouge"><div
class="highlight"><pre class="highlight"><code> @StrutsParameter
- public String name; // Accepts: ?name=value
-</code></pre></div> </div>
- </li>
- <li><code class="language-plaintext highlighter-rouge">depth = 1</code>:
Allows one level of nesting
- <div class="language-plaintext highlighter-rouge"><div
class="highlight"><pre class="highlight"><code> @StrutsParameter(depth = 1)
- public User user; // Accepts: ?user.name=value
-</code></pre></div> </div>
- </li>
- <li><code class="language-plaintext highlighter-rouge">depth = 2</code>:
Allows two levels of nesting
- <div class="language-plaintext highlighter-rouge"><div
class="highlight"><pre class="highlight"><code> @StrutsParameter(depth = 2)
- public User user; // Accepts: ?user.address.city=value
-</code></pre></div> </div>
- </li>
-</ul>
+<h3 id="collections">Collections</h3>
+
+<h4 id="populating-a-collection-of-simple-types">Populating a collection of
simple types</h4>
-<p>Rule of thumb: The depth equals the number of dots (or brackets) allowed in
the parameter name.</p>
+<p>When populating a collection of simple types (e.g., from a checkbox list),
annotate the setter.</p>
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="nc">List</span><span
class="o"><</span><span class="nc">String</span><span class="o">></span>
<span class="n">mySelection</span><span class="o">;</span>
+
+ <span class="nd">@StrutsParameter</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">setMySelection</span><span class="o">(</span><span
class="nc">List</span><span class="o"><</span><span
class="nc">String</span><span class="o">></span> <span
class="n">mySelection</span><span class="o">)</span> <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span
class="na">mySelection</span> <span class="o">=</span> <span
class="n">mySelection</span><span class="o">;</span>
+ <span class="o">}</span>
+ <span class="c1">// ... getter</span>
+<span class="o">}</span>
+</code></pre></div></div>
+
+<h4 id="populating-properties-of-objects-within-a-collection">Populating
properties of objects within a collection</h4>
+
+<p>When populating properties of objects that are already in a collection,
annotate the getter.</p>
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="nc">List</span><span
class="o"><</span><span class="nc">User</span><span class="o">></span>
<span class="n">users</span><span class="o">;</span> <span class="c1">// assume
this is initialized in the constructor or elsewhere</span>
+
+ <span class="nd">@StrutsParameter</span><span class="o">(</span><span
class="n">depth</span> <span class="o">=</span> <span class="mi">1</span><span
class="o">)</span>
+ <span class="kd">public</span> <span class="nc">List</span><span
class="o"><</span><span class="nc">User</span><span class="o">></span>
<span class="nf">getUsers</span><span class="o">()</span> <span
class="o">{</span>
+ <span class="k">return</span> <span class="n">users</span><span
class="o">;</span>
+ <span class="o">}</span>
+ <span class="c1">// ...</span>
+<span class="o">}</span>
+</code></pre></div></div>
+<p>This allows requests like <code class="language-plaintext
highlighter-rouge">users[0].name=John</code>.</p>
+
+<h3 id="complex-object">Complex object</h3>
+
+<h4 id="populating-the-object-itself">Populating the object itself</h4>
+
+<p>To populate the whole object from the request (e.g., using a custom type
converter), annotate the setter.</p>
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="nc">User</span> <span
class="n">user</span><span class="o">;</span>
+
+ <span class="nd">@StrutsParameter</span>
+ <span class="kd">public</span> <span class="kt">void</span> <span
class="nf">setUser</span><span class="o">(</span><span class="nc">User</span>
<span class="n">user</span><span class="o">)</span> <span class="o">{</span>
+ <span class="k">this</span><span class="o">.</span><span
class="na">user</span> <span class="o">=</span> <span
class="n">user</span><span class="o">;</span>
+ <span class="o">}</span>
+ <span class="c1">// ... getter</span>
+<span class="o">}</span>
+</code></pre></div></div>
+
+<h4 id="populating-properties-of-a-complex-object">Populating properties of a
complex object</h4>
+
+<p>To populate the properties of a complex object, annotate the getter.</p>
+<div class="language-java highlighter-rouge"><div class="highlight"><pre
class="highlight"><code><span class="kd">public</span> <span
class="kd">class</span> <span class="nc">MyAction</span> <span
class="o">{</span>
+ <span class="kd">private</span> <span class="nc">User</span> <span
class="n">user</span> <span class="o">=</span> <span class="k">new</span> <span
class="nc">User</span><span class="o">();</span>
+
+ <span class="nd">@StrutsParameter</span><span class="o">(</span><span
class="n">depth</span> <span class="o">=</span> <span class="mi">1</span><span
class="o">)</span>
+ <span class="kd">public</span> <span class="nc">User</span> <span
class="nf">getUser</span><span class="o">()</span> <span class="o">{</span>
+ <span class="k">return</span> <span class="n">user</span><span
class="o">;</span>
+ <span class="o">}</span>
+<span class="o">}</span>
+</code></pre></div></div>
+<p>This allows requests like <code class="language-plaintext
highlighter-rouge">user.name=John</code>.</p>
</section>
</article>