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

asf-gitbox-commits pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/struts-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new f793f2fca Automatic Site Publish by Buildbot
f793f2fca is described below

commit f793f2fca798d7756910f634b32f0e7c74796592
Author: buildbot <[email protected]>
AuthorDate: Fri Oct 2 10:19:19 2026 +0000

    Automatic Site Publish by Buildbot
---
 output/core-developers/action-mapper.html          |  3 +-
 .../execute-and-wait-interceptor.html              | 35 +++++++++++-
 output/core-developers/restful-action-mapper.html  |  7 +++
 .../struts-parameter-annotation.html               | 65 +++++++++++++++++-----
 output/plugins/bean-validation/index.html          |  8 +++
 output/plugins/jasperreports/index.html            |  5 +-
 output/plugins/jasperreports7/index.html           | 19 ++++++-
 output/plugins/rest/index.html                     | 49 ++++++++++++++++
 8 files changed, 171 insertions(+), 20 deletions(-)

diff --git a/output/core-developers/action-mapper.html 
b/output/core-developers/action-mapper.html
index 2445fb460..6e1c5eb93 100644
--- a/output/core-developers/action-mapper.html
+++ b/output/core-developers/action-mapper.html
@@ -305,7 +305,8 @@ methods.</p>
 </code></pre></div></div>
 
 <p><code class="language-plaintext 
highlighter-rouge">CompositeActionMapper</code> will be configured with 2 
ActionMapper, namely “struts” which is <code class="language-plaintext 
highlighter-rouge">org.apache.struts2.dispatcher.mapper.DefaultActionMapper</code>
-and “restful” which is <code class="language-plaintext 
highlighter-rouge">org.apache.struts2.dispatcher.mapper.RestfulActionMapper</code>.</p>
+and “restful” which is <code class="language-plaintext 
highlighter-rouge">org.apache.struts2.dispatcher.mapper.RestfulActionMapper</code>.
 The <code class="language-plaintext highlighter-rouge">restful</code> and 
<code class="language-plaintext highlighter-rouge">restful2</code> mappers
+are deprecated since 7.4.0 and 6.12.0, see <a 
href="restful-action-mapper">RestfulActionMapper</a>.</p>
 
 <p><code class="language-plaintext 
highlighter-rouge">CompositeActionMapper</code> would consult each of them in 
order described above.</p>
 
diff --git a/output/core-developers/execute-and-wait-interceptor.html 
b/output/core-developers/execute-and-wait-interceptor.html
index ed00e435a..ed45f0828 100644
--- a/output/core-developers/execute-and-wait-interceptor.html
+++ b/output/core-developers/execute-and-wait-interceptor.html
@@ -156,7 +156,10 @@
 
 <ul id="markdown-toc">
   <li><a href="#parameters" id="markdown-toc-parameters">Parameters</a></li>
-  <li><a href="#extending-the-interceptor" 
id="markdown-toc-extending-the-interceptor">Extending the Interceptor</a></li>
+  <li><a href="#extending-the-interceptor" 
id="markdown-toc-extending-the-interceptor">Extending the Interceptor</a>    
<ul>
+      <li><a href="#one-background-process-per-browser-tab" 
id="markdown-toc-one-background-process-per-browser-tab">One background process 
per browser tab</a></li>
+    </ul>
+  </li>
   <li><a href="#using-executorprovider" 
id="markdown-toc-using-executorprovider">Using ExecutorProvider</a></li>
   <li><a href="#examples" id="markdown-toc-examples">Examples</a>    <ul>
       <li><a href="#example-code-1" id="markdown-toc-example-code-1">Example 
code 1</a></li>
@@ -225,6 +228,36 @@ for obtaining and releasing resources that the background 
process will need to e
 background
 process extension, extend <code class="language-plaintext 
highlighter-rouge">ExecuteAndWaitInterceptor</code> and implement the <code 
class="language-plaintext highlighter-rouge">getNewBackgroundProcess()</code> 
method.</p>
 
+<h3 id="one-background-process-per-browser-tab">One background process per 
browser tab</h3>
+
+<p>The background process is keyed by action name alone, so a second browser 
tab of the same session joins the process
+already running instead of starting its own. Override <code 
class="language-plaintext 
highlighter-rouge">getBackgroundProcessName(ActionProxy)</code> to widen that 
key, for
+example with the transaction token, so that each tab gets its own process:</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">TokenizedExecuteAndWaitInterceptor</span> <span 
class="kd">extends</span> <span class="nc">ExecuteAndWaitInterceptor</span> 
<span class="o">{</span>
+    <span class="nd">@Override</span>
+    <span class="kd">protected</span> <span class="nc">String</span> <span 
class="nf">getBackgroundProcessName</span><span class="o">(</span><span 
class="nc">ActionProxy</span> <span class="n">proxy</span><span 
class="o">)</span> <span class="o">{</span>
+        <span class="nc">String</span> <span class="n">token</span> <span 
class="o">=</span> <span class="nc">TokenHelper</span><span 
class="o">.</span><span class="na">getToken</span><span class="o">();</span>
+        <span class="k">return</span> <span class="n">token</span> <span 
class="o">==</span> <span class="kc">null</span>
+            <span class="o">?</span> <span class="kd">super</span><span 
class="o">.</span><span class="na">getBackgroundProcessName</span><span 
class="o">(</span><span class="n">proxy</span><span class="o">)</span>
+            <span class="o">:</span> <span class="kd">super</span><span 
class="o">.</span><span class="na">getBackgroundProcessName</span><span 
class="o">(</span><span class="n">proxy</span><span class="o">)</span> <span 
class="o">+</span> <span class="s">"_"</span> <span class="o">+</span> <span 
class="n">token</span><span class="o">;</span>
+    <span class="o">}</span>
+<span class="o">}</span>
+</code></pre></div></div>
+
+<p>Two caveats apply to any key that varies per request:</p>
+
+<ul>
+  <li>the entry is dropped from the session only when a request observes the 
process as done, so every run the user
+abandons leaves a background process, and the action instance it holds, in the 
session. With the action-name key
+that is at most one per action; with a per-tab key it grows without limit.</li>
+  <li>the wait page must send the value used in the key on every refresh, for 
instance with <code class="language-plaintext highlighter-rouge">&lt;s:url 
includeParams="all"/&gt;</code>
+together with the <a href="token-interceptor">Token Interceptor</a>. Otherwise 
each refresh starts another background process
+instead of joining the running one.</li>
+</ul>
+
+<p>See <a href="https://issues.apache.org/jira/browse/WW-1742";>WW-1742</a>.</p>
+
 <h2 id="using-executorprovider">Using ExecutorProvider</h2>
 
 <p>Since Struts 6.2.0 it is possible to use your own <code 
class="language-plaintext highlighter-rouge">ExecutorProvider</code> to run 
<em>background tasks</em>. To use your own executor
diff --git a/output/core-developers/restful-action-mapper.html 
b/output/core-developers/restful-action-mapper.html
index 99a3477a7..9760056ad 100644
--- a/output/core-developers/restful-action-mapper.html
+++ b/output/core-developers/restful-action-mapper.html
@@ -155,6 +155,7 @@
     <h1 class="no_toc" id="restfulactionmapper">RestfulActionMapper</h1>
 
 <ul id="markdown-toc">
+  <li><a href="#restfulactionmapper-1" 
id="markdown-toc-restfulactionmapper-1">RestfulActionMapper</a></li>
   <li><a href="#restful2actionmapper" 
id="markdown-toc-restful2actionmapper">Restful2ActionMapper</a>    <ul>
       <li><a href="#example" id="markdown-toc-example">Example</a></li>
       <li><a href="#unit-testing" id="markdown-toc-unit-testing">Unit 
testing</a></li>
@@ -162,6 +163,12 @@
   </li>
 </ul>
 
+<p class="alert alert-warning"><code class="language-plaintext 
highlighter-rouge">RestfulActionMapper</code> and <code 
class="language-plaintext highlighter-rouge">Restful2ActionMapper</code> are 
deprecated since Struts 7.4.0 and 6.12.0 and will be removed in a
+future release (<a 
href="https://issues.apache.org/jira/browse/WW-5707";>WW-5707</a>). Both predate 
the
+<a href="../plugins/rest">REST Plugin</a>, which is the maintained way to 
build REST-style applications; use it instead.</p>
+
+<h2 id="restfulactionmapper-1">RestfulActionMapper</h2>
+
 <p>A custom action mapper using the following format:</p>
 
 <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code>http://HOST/ACTION_NAME/PARAM_NAME1/PARAM_VALUE1/PARAM_NAME2/PARAM_VALUE2
diff --git a/output/core-developers/struts-parameter-annotation.html 
b/output/core-developers/struts-parameter-annotation.html
index 28dc7fd8d..4cddbdeb5 100644
--- a/output/core-developers/struts-parameter-annotation.html
+++ b/output/core-developers/struts-parameter-annotation.html
@@ -157,6 +157,7 @@
 <ul id="markdown-toc">
   <li><a href="#where-authorization-applies" 
id="markdown-toc-where-authorization-applies">Where authorization applies</a>   
 <ul>
       <li><a href="#creator-bound-properties" 
id="markdown-toc-creator-bound-properties">Creator-bound properties</a></li>
+      <li><a href="#rest-body-properties-are-matched-by-their-java-name" 
id="markdown-toc-rest-body-properties-are-matched-by-their-java-name">REST body 
properties are matched by their Java name</a></li>
       <li><a href="#jackson-any-setters" 
id="markdown-toc-jackson-any-setters">Jackson any-setters</a></li>
     </ul>
   </li>
@@ -193,7 +194,7 @@ action chaining (opt-in via <code class="language-plaintext 
highlighter-rouge">s
   <li><a href="../../plugins/json">JSON</a> and <a 
href="../../plugins/rest">REST</a> plugins — per-property
 authorization performed during deserialization, so an unauthorized property is 
not set on
 the target object. This covers the properties the deserializer binds 
<strong>by name</strong>; in the
-REST plugin a Jackson any-setter is a separate sink that is not covered — see
+REST plugin a Jackson any-setter is covered only when you opt in — see
 <a href="#jackson-any-setters">Jackson any-setters</a> below.</li>
 </ul>
 
@@ -215,25 +216,61 @@ object under construction is dropped instead of failing 
the request.</p>
 the same way as any nested object: <code class="language-plaintext 
highlighter-rouge">@StrutsParameter(depth = ...)</code> on the getter that 
reaches them, or a <code class="language-plaintext 
highlighter-rouge">ModelDriven</code>
 model. Otherwise those values silently stop arriving.</p>
 
+<h3 id="rest-body-properties-are-matched-by-their-java-name">REST body 
properties are matched by their Java name</h3>
+
+<p>The REST plugin authorizes a request-body property against the Java member 
Jackson writes to — the
+field, or the bean property its setter is named after — not against the name 
used on the wire. A
+member renamed with <code class="language-plaintext 
highlighter-rouge">@JsonProperty</code>, <code class="language-plaintext 
highlighter-rouge">@JsonAlias</code> or a <code class="language-plaintext 
highlighter-rouge">PropertyNamingStrategy</code> is authorized by the
+annotation on that member. Up to Struts 7.3.0 the wire name was used, so a 
renamed annotated member
+was rejected as unannotated (<a 
href="https://issues.apache.org/jira/browse/WW-5715";>WW-5715</a>).</p>
+
+<p>Since Struts 7.4.0 two more REST paths are checked like any other 
property:</p>
+
+<ul>
+  <li>the id property of a type using a property-based <code 
class="language-plaintext highlighter-rouge">@JsonIdentityInfo</code>
+(<a href="https://issues.apache.org/jira/browse/WW-5727";>WW-5727</a>);</li>
+  <li>a polymorphic (<code class="language-plaintext 
highlighter-rouge">@JsonTypeInfo</code>) property that is mergeable and already 
holds a value. The body is no longer merged
+into the existing value; the property is replaced through the authorized path, 
so the body must carry the type id
+(<a href="https://issues.apache.org/jira/browse/WW-5726";>WW-5726</a>).</li>
+</ul>
+
 <h3 id="jackson-any-setters">Jackson any-setters</h3>
 
 <p>A class that declares a Jackson any-setter — <code 
class="language-plaintext highlighter-rouge">@JsonAnySetter</code> on a method, 
on a field, or on a
 <code class="language-plaintext highlighter-rouge">@JsonCreator</code> 
parameter — tells Jackson to route <strong>every otherwise-unknown key</strong> 
in the request body
 to that member. The REST plugin’s authorization wrapper covers the properties 
Jackson binds by name;
-an any-setter is a separate sink and is not wrapped. Keys arriving through it 
are therefore set
-without an <code class="language-plaintext 
highlighter-rouge">@StrutsParameter</code> check, even with <code 
class="language-plaintext 
highlighter-rouge">struts.parameters.requireAnnotations</code> enabled, and
-even in the same request in which an ordinary unannotated setter on the same 
class is correctly
-rejected.</p>
+by default an any-setter is not wrapped, so keys arriving through it are set 
without an
+<code class="language-plaintext highlighter-rouge">@StrutsParameter</code> 
check, even with <code class="language-plaintext 
highlighter-rouge">struts.parameters.requireAnnotations</code> enabled.</p>
+
+<p>Since Struts 7.4.0 you can bring any-setters under authorization by setting
+<code class="language-plaintext 
highlighter-rouge">struts.rest.anySetter.requireAnnotations</code> to <code 
class="language-plaintext highlighter-rouge">true</code>
+(<a href="https://issues.apache.org/jira/browse/WW-5712";>WW-5712</a>). The 
setting defaults to <code class="language-plaintext 
highlighter-rouge">false</code> for compatibility and,
+like the rest of REST body authorization, takes effect only when <code 
class="language-plaintext 
highlighter-rouge">struts.parameters.requireAnnotations</code> is enabled.
+With it on, an any-setter receives keys only when the method or field carries
+<code class="language-plaintext 
highlighter-rouge">@StrutsParameter(allowDynamicKeys = true)</code>:</p>
+
+<div class="language-java highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code><span class="nd">@StrutsParameter</span><span 
class="o">(</span><span class="n">allowDynamicKeys</span> <span 
class="o">=</span> <span class="kc">true</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="nd">@JsonAnySetter</span>
+<span class="kd">public</span> <span class="kt">void</span> <span 
class="nf">setExtra</span><span class="o">(</span><span 
class="nc">String</span> <span class="n">key</span><span class="o">,</span> 
<span class="nc">Object</span> <span class="n">value</span><span 
class="o">)</span> <span class="o">{</span>
+    <span class="n">extras</span><span class="o">.</span><span 
class="na">put</span><span class="o">(</span><span class="n">key</span><span 
class="o">,</span> <span class="n">value</span><span class="o">);</span>
+<span class="o">}</span>
+</code></pre></div></div>
+
+<p><code class="language-plaintext highlighter-rouge">depth</code> limits how 
deeply nested each dynamic key’s value may be: <code class="language-plaintext 
highlighter-rouge">depth = 0</code> accepts scalar values only, <code 
class="language-plaintext highlighter-rouge">depth = 1</code>
+also accepts an object or array one level deep. A key whose any-setter is 
unannotated, or whose value is nested deeper
+than allowed, is dropped. An any-setter on a <code class="language-plaintext 
highlighter-rouge">@JsonCreator</code> parameter rejects every key. Rejected 
keys are logged as
+one WARN per any-setter and reason, not one per key. <code 
class="language-plaintext highlighter-rouge">allowDynamicKeys</code> has no 
effect on ordinary request parameters.</p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code><span class="nt">&lt;constant</span> <span 
class="na">name=</span><span 
class="s">"struts.rest.anySetter.requireAnnotations"</span> <span 
class="na">value=</span><span class="s">"true"</span><span 
class="nt">/&gt;</span>
+</code></pre></div></div>
 
-<p>Two limits are worth knowing. An any-setter beneath an <strong>unauthorized 
parent</strong> is still unreachable:
-the parent is rejected first and its whole subtree is skipped. And <code 
class="language-plaintext highlighter-rouge">@JsonUnwrapped</code> is a named
-property, so it is unaffected by this.</p>
+<p>An any-setter beneath an <strong>unauthorized parent</strong> is 
unreachable either way: the parent is rejected first and its whole
+subtree is skipped. <code class="language-plaintext 
highlighter-rouge">@JsonUnwrapped</code> is a named property, so it is 
unaffected by this.</p>
 
-<p class="alert alert-warning">Declaring an any-setter on a class bound from a 
REST request body is the application accepting
-arbitrary names and values off the wire — the same decision as binding a <code 
class="language-plaintext highlighter-rouge">Map</code>, and it deserves the
-same scrutiny. Where that is not what you want, do not declare one on a 
request-bound class, or
-narrow what the method accepts before storing it. Tracked as
-<a href="https://issues.apache.org/jira/browse/WW-5712";>WW-5712</a>.</p>
+<p class="alert alert-warning">With <code class="language-plaintext 
highlighter-rouge">struts.rest.anySetter.requireAnnotations</code> left at 
<code class="language-plaintext highlighter-rouge">false</code>, declaring an 
any-setter on a class bound from a REST
+request body is the application accepting arbitrary names and values off the 
wire — the same decision as binding a
+<code class="language-plaintext highlighter-rouge">Map</code>, and it deserves 
the same scrutiny. Enable the setting, do not declare an any-setter on a 
request-bound class, or
+narrow what the method accepts before storing it.</p>
 
 <h2 id="modeldriven-actions">ModelDriven actions</h2>
 
@@ -302,7 +339,7 @@ bindable, use action properties annotated with <code 
class="language-plaintext h
 <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><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:
+  <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. Since Struts 7.4.0 this includes fluent setters that return a value 
instead of <code class="language-plaintext highlighter-rouge">void</code>; 
before, an annotation on a fluent setter was ignored (<a 
href="https://issues.apache.org/jira/browse/WW-5709";>WW-5709</a>). This applies 
to:
     <ul>
       <li>Simple types (String, int, boolean, etc.).</li>
       <li>Checkboxes (single or multiple values).</li>
diff --git a/output/plugins/bean-validation/index.html 
b/output/plugins/bean-validation/index.html
index 5574b0311..177b58e4e 100644
--- a/output/plugins/bean-validation/index.html
+++ b/output/plugins/bean-validation/index.html
@@ -209,6 +209,14 @@ by extending your own application package from <code 
class="language-plaintext h
 <span class="nt">&lt;/struts&gt;</span>
 </code></pre></div></div>
 
+<p class="alert alert-warning">Since Struts 7.4.0 and 6.12.0 the plugin’s 
<code class="language-plaintext 
highlighter-rouge">beanValidationDefaultStack</code> contains the
+<a href="/core-developers/coep-interceptor"><code class="language-plaintext 
highlighter-rouge">coep</code></a>, <a 
href="/core-developers/coop-interceptor"><code class="language-plaintext 
highlighter-rouge">coop</code></a> and
+<a href="/core-developers/fetch-metadata-interceptor"><code 
class="language-plaintext highlighter-rouge">fetchMetadata</code></a> 
interceptors, configured as in core’s <code class="language-plaintext 
highlighter-rouge">defaultStack</code>
+(<a href="https://issues.apache.org/jira/browse/WW-5718";>WW-5718</a>). Earlier 
versions left them out. Cross-site requests that
+use a method other than GET and are not navigations are now rejected: the 
action is not invoked and the interceptor
+returns the result code <code class="language-plaintext 
highlighter-rouge">403</code>, which needs a matching (global) result to render 
a response. Set
+<code class="language-plaintext 
highlighter-rouge">fetchMetadata.disabled</code> to <code 
class="language-plaintext highlighter-rouge">true</code> on the stack for 
actions that must accept such requests.</p>
+
 <p>Here is another example that shows how you can combine bean-validation with 
other plugins by configuring your own
 Interceptor-Stack (note: this is just a very short example. In a real app you 
should take more care about your stack).
 You can combine bean validation with classic struts validation (or disable 
either) by putting the according interceptors
diff --git a/output/plugins/jasperreports/index.html 
b/output/plugins/jasperreports/index.html
index f20759675..311057b1f 100644
--- a/output/plugins/jasperreports/index.html
+++ b/output/plugins/jasperreports/index.html
@@ -199,7 +199,10 @@ If no format is specified, PDF will be used</li>
   <li>imageServletUrl - name of the url that, when prefixed with the context 
page, can return report images</li>
   <li>reportParameters - (since 2.1.2+) OGNL expression used to retrieve a map 
of report parameters from the value stack. 
 The parameters may be accessed in the report via the usual JR mechanism and 
might include data not part of the 
-dataSource, such as the user name of the report creator, etc.</li>
+dataSource, such as the user name of the report creator, etc.
+A report parameter that is not in this map is looked up on the value stack by 
its name, so a parameter <code class="language-plaintext 
highlighter-rouge">title</code>
+receives the action’s <code class="language-plaintext 
highlighter-rouge">getTitle()</code>. This lookup did not reach JasperReports 
from 6.0.0 to 7.3.0, so those
+parameters were <code class="language-plaintext 
highlighter-rouge">null</code>; it works again since 7.4.0 (<a 
href="https://issues.apache.org/jira/browse/WW-5729";>WW-5729</a>).</li>
   <li>exportParameters - (since 2.1.2+) OGNL expression used to retrieve a map 
of JR exporter parameters from the value stack.
 The export parameters are used to customize the JR export. For example, a PDF 
export might enable encryption 
 and set the user password to a string known to the report creator.</li>
diff --git a/output/plugins/jasperreports7/index.html 
b/output/plugins/jasperreports7/index.html
index afef9728b..026239dc9 100644
--- a/output/plugins/jasperreports7/index.html
+++ b/output/plugins/jasperreports7/index.html
@@ -361,8 +361,9 @@ extension when <code class="language-plaintext 
highlighter-rouge">documentName</
 <h3 id="installation">Installation</h3>
 
 <p>This plugin can be installed by copying the plugin jar into your 
application’s <code class="language-plaintext 
highlighter-rouge">/WEB-INF/lib</code> directory. The plugin
-brings the JasperReports 7 core library with it, but the PDF exporter lives in 
a separate JasperReports artifact
-which is an optional dependency of the plugin. As <code 
class="language-plaintext highlighter-rouge">pdf</code> is the default format, 
most applications need to add it:</p>
+does not bring JasperReports with it: add the <code class="language-plaintext 
highlighter-rouge">jasperreports</code> library yourself, and the <code 
class="language-plaintext highlighter-rouge">jasperreports-pdf</code> exporter 
as
+well when you produce PDF output, which as the default format most 
applications do. The plugin is built against
+JasperReports 7.0.7.</p>
 
 <div class="language-xml highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code><span class="nt">&lt;dependencies&gt;</span>
    ...
@@ -371,6 +372,11 @@ which is an optional dependency of the plugin. As <code 
class="language-plaintex
        <span 
class="nt">&lt;artifactId&gt;</span>struts2-jasperreports7-plugin<span 
class="nt">&lt;/artifactId&gt;</span>
        <span class="nt">&lt;version&gt;</span>STRUTS_VERSION<span 
class="nt">&lt;/version&gt;</span>
    <span class="nt">&lt;/dependency&gt;</span>
+   <span class="nt">&lt;dependency&gt;</span>
+       <span class="nt">&lt;groupId&gt;</span>net.sf.jasperreports<span 
class="nt">&lt;/groupId&gt;</span>
+       <span class="nt">&lt;artifactId&gt;</span>jasperreports<span 
class="nt">&lt;/artifactId&gt;</span>
+       <span class="nt">&lt;version&gt;</span>JASPERREPORTS_VERSION<span 
class="nt">&lt;/version&gt;</span>
+   <span class="nt">&lt;/dependency&gt;</span>
    <span class="nt">&lt;dependency&gt;</span>
        <span class="nt">&lt;groupId&gt;</span>net.sf.jasperreports<span 
class="nt">&lt;/groupId&gt;</span>
        <span class="nt">&lt;artifactId&gt;</span>jasperreports-pdf<span 
class="nt">&lt;/artifactId&gt;</span>
@@ -380,7 +386,14 @@ which is an optional dependency of the plugin. As <code 
class="language-plaintex
 <span class="nt">&lt;/dependencies&gt;</span>
 </code></pre></div></div>
 
-<p>Use the same <code class="language-plaintext 
highlighter-rouge">JASPERREPORTS_VERSION</code> as the <code 
class="language-plaintext highlighter-rouge">jasperreports</code> artifact 
pulled in by the plugin.</p>
+<p>Use the same <code class="language-plaintext 
highlighter-rouge">JASPERREPORTS_VERSION</code> for both artifacts.</p>
+
+<p class="alert alert-warning">Struts 7.1.0 to 7.3.0 declared <code 
class="language-plaintext highlighter-rouge">jasperreports</code> as a compile 
dependency of the plugin, so it arrived transitively and
+was bundled in the release distribution. JasperReports is LGPL licensed and 
cannot be shipped in an Apache release,
+so since 7.4.0 it is a <code class="language-plaintext 
highlighter-rouge">provided</code> dependency, as it has always been in the
+<a href="../jasperreports">JasperReports Plugin</a> (<a 
href="https://issues.apache.org/jira/browse/WW-5735";>WW-5735</a>). When 
upgrading,
+add the <code class="language-plaintext 
highlighter-rouge">jasperreports</code> dependency yourself, otherwise the 
application fails at runtime with missing JasperReports
+classes.</p>
 
 <h2 id="migrating-from-the-jasperreports-plugin">Migrating from the 
JasperReports plugin</h2>
 
diff --git a/output/plugins/rest/index.html b/output/plugins/rest/index.html
index a9e0c7f43..cfb3f89de 100644
--- a/output/plugins/rest/index.html
+++ b/output/plugins/rest/index.html
@@ -177,6 +177,8 @@
       <li><a href="#xstream-configuration" 
id="markdown-toc-xstream-configuration">XStream configuration</a></li>
       <li><a href="#custom-contenttypehandlers" 
id="markdown-toc-custom-contenttypehandlers">Custom ContentTypeHandlers</a></li>
       <li><a href="#settings" id="markdown-toc-settings">Settings</a></li>
+      <li><a href="#request-body-size-limit" 
id="markdown-toc-request-body-size-limit">Request body size limit</a></li>
+      <li><a href="#resource-isolation-in-restdefaultstack" 
id="markdown-toc-resource-isolation-in-restdefaultstack">Resource isolation in 
restDefaultStack</a></li>
     </ul>
   </li>
   <li><a href="#resources" id="markdown-toc-resources">Resources</a></li>
@@ -601,9 +603,56 @@ For more configuration options see the <a 
href="../convention">Convention Plugin
       <td>true</td>
       <td>eg. put struts.rest.content.restrictToGET = false in 
struts.properties</td>
     </tr>
+    <tr>
+      <td>struts.rest.content.maxLength</td>
+      <td>Maximum number of characters read from a request body, see <a 
href="#request-body-size-limit">Request body size limit</a>. Since 7.4.0 and 
6.12.0</td>
+      <td>2097152</td>
+      <td>Any integer of 1 or more</td>
+    </tr>
+    <tr>
+      <td>struts.rest.anySetter.requireAnnotations</td>
+      <td>Whether keys bound through a Jackson any-setter require <code 
class="language-plaintext highlighter-rouge">@StrutsParameter(allowDynamicKeys 
= true)</code>, see <a 
href="/core-developers/struts-parameter-annotation#jackson-any-setters">Jackson 
any-setters</a>. Since 7.4.0</td>
+      <td>false</td>
+      <td>true, false</td>
+    </tr>
   </tbody>
 </table>
 
+<h3 id="request-body-size-limit">Request body size limit</h3>
+
+<p>Since Struts 7.4.0 and 6.12.0 the plugin stops reading a request body once 
it passes <code class="language-plaintext 
highlighter-rouge">struts.rest.content.maxLength</code>
+characters (2 MB by default, the same as <code class="language-plaintext 
highlighter-rouge">struts.json.maxLength</code> in the <a href="../json">JSON 
plugin</a>) and fails the request
+with a <code class="language-plaintext 
highlighter-rouge">RequestBodyTooLargeException</code> before the action runs
+(<a href="https://issues.apache.org/jira/browse/WW-5723";>WW-5723</a>). The 
limit is applied while the content-type handler reads
+the body, so requests whose handler never reads it — HTML, form-urlencoded, 
multipart — are not affected.</p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code><span class="nt">&lt;constant</span> <span 
class="na">name=</span><span class="s">"struts.rest.content.maxLength"</span> 
<span class="na">value=</span><span class="s">"10485760"</span><span 
class="nt">/&gt;</span>
+</code></pre></div></div>
+
+<p class="alert alert-warning">An API that accepts JSON or XML payloads larger 
than 2 MB must raise <code class="language-plaintext 
highlighter-rouge">struts.rest.content.maxLength</code> when upgrading,
+otherwise those requests start failing.</p>
+
+<h3 id="resource-isolation-in-restdefaultstack">Resource isolation in 
restDefaultStack</h3>
+
+<p>Since Struts 7.4.0 and 6.12.0 <code class="language-plaintext 
highlighter-rouge">restDefaultStack</code> contains the <a 
href="/core-developers/coep-interceptor"><code class="language-plaintext 
highlighter-rouge">coep</code></a>,
+<a href="/core-developers/coop-interceptor"><code class="language-plaintext 
highlighter-rouge">coop</code></a> and <a 
href="/core-developers/fetch-metadata-interceptor"><code 
class="language-plaintext highlighter-rouge">fetchMetadata</code></a>
+interceptors, configured as in core’s <code class="language-plaintext 
highlighter-rouge">defaultStack</code>
+(<a href="https://issues.apache.org/jira/browse/WW-5718";>WW-5718</a>). Earlier 
versions left them out, so a package extending
+<code class="language-plaintext highlighter-rouge">rest-default</code> sent no 
COOP/COEP headers and skipped the Fetch Metadata check. A request rejected by 
the Fetch Metadata
+check is answered with HTTP status 403 and no response body.</p>
+
+<p class="alert alert-warning">The Fetch Metadata check rejects browser 
requests sent with <code class="language-plaintext 
highlighter-rouge">Sec-Fetch-Site: cross-site</code> that use a method other
+than GET and are not navigations, which includes <code 
class="language-plaintext highlighter-rouge">POST</code>, <code 
class="language-plaintext highlighter-rouge">PUT</code> and <code 
class="language-plaintext highlighter-rouge">DELETE</code> calls made with 
<code class="language-plaintext highlighter-rouge">fetch()</code>/XHR from a
+single-page application served from another site. If your REST API is meant to 
be called from such a page, disable the
+check for the stack serving it:</p>
+
+<div class="language-xml highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code><span class="nt">&lt;interceptor-ref</span> <span 
class="na">name=</span><span class="s">"restDefaultStack"</span><span 
class="nt">&gt;</span>
+    <span class="nt">&lt;param</span> <span class="na">name=</span><span 
class="s">"fetchMetadata.disabled"</span><span class="nt">&gt;</span>true<span 
class="nt">&lt;/param&gt;</span>
+<span class="nt">&lt;/interceptor-ref&gt;</span>
+</code></pre></div></div>
+
+<p>Requests sent by non-browser clients carry no <code 
class="language-plaintext highlighter-rouge">Sec-Fetch-Site</code> header and 
are not affected.</p>
+
 <h2 id="resources">Resources</h2>
 
 <ul>

Reply via email to