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

lukaszlenart pushed a commit to branch docs/struts-7.2.0-documentation-updates
in repository https://gitbox.apache.org/repos/asf/struts-site.git

commit b3626f1334dd1f318481ed97a5f3da7304203ba8
Author: Lukasz Lenart <[email protected]>
AuthorDate: Tue Feb 17 07:36:12 2026 +0100

    docs: add documentation for Struts 7.2.0 new features and changes
    
    - Checkbox hidden field prefix constant (WW-3429)
    - Spring autowire alwaysRespect default change to true (WW-3647)
    - Spring bean names support in type converters (WW-4291)
    - Preparable.prepare() default method (WW-5588)
    - Dynamic file upload validation parameters (WW-5585)
    - @Validations annotation fix for doubleRange/shortRange (WW-5579)
    - JSP direct access security warning (WW-5294)
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude <[email protected]>
---
 .claude/settings.json                              |   5 +-
 CLAUDE.md                                          | 141 ++++++++-------------
 .../action-file-upload-interceptor.md              |  19 ++-
 source/core-developers/prepare-interceptor.md      |   6 +-
 source/core-developers/type-conversion.md          |  11 +-
 source/plugins/spring/index.md                     |  15 ++-
 source/security/index.md                           |   9 +-
 source/tag-developers/checkbox-tag.md              |  18 +++
 8 files changed, 128 insertions(+), 96 deletions(-)

diff --git a/.claude/settings.json b/.claude/settings.json
index a22e52465..d78853e27 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -7,12 +7,15 @@
       "WebFetch(domain:github.com)",
       "WebFetch(domain:struts.apache.org)",
       "WebFetch(domain:raw.githubusercontent.com)",
+      "WebFetch(domain:cwiki.apache.org)",
       "Bash(git checkout:*)",
       "Bash(git add:*)",
       "Bash(git commit:*)",
       "Bash(git push:*)",
       "Bash(gh pr create:*)",
-      "Bash(gh pr view:*)"
+      "Bash(gh pr view:*)",
+      "Bash(gh pr diff:*)",
+      "Bash(ls:*)"
     ],
     "deny": [],
     "ask": []
diff --git a/CLAUDE.md b/CLAUDE.md
index de11465d0..16811823d 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -4,122 +4,89 @@ This file provides guidance to Claude Code (claude.ai/code) 
when working with co
 
 ## Project Overview
 
-This is the Apache Struts website repository, which powers 
https://struts.apache.org/. The site is built with Jekyll and uses a mix of 
Markdown and HTML files.
+This is the Apache Struts website repository, which powers 
https://struts.apache.org/. The site is built with Jekyll 4.2 and uses a mix of 
Markdown and HTML files.
 
 ## Development Commands
 
 ### Running the Site Locally
 
-The site can be run locally using Jekyll or Docker:
-
-**Using Jekyll directly:**
-```bash
-bundle exec jekyll serve -w --trace --host 0.0.0.0
-```
-
-**Using Docker (recommended):**
 ```bash
-# Build the Docker image (only needed when Dockerfile changes)
-./docker-build.sh
+# Using Docker (recommended, Apple Silicon)
+./docker-build.sh          # Build image (only when Dockerfile changes)
+./docker-arm64-serve.sh    # Serve site at http://localhost:4000
 
-# Run the site in Docker
-./docker-arm64-serve.sh  # For ARM64 architecture (Apple Silicon)
-```
-
-The site will be available at http://localhost:4000
-
-### Installing Dependencies
-
-```bash
-bundle install
+# Using Jekyll directly
+bundle install             # Install dependencies
+bundle exec jekyll serve -w --trace --host 0.0.0.0
 ```
 
-## Directory Structure
-
-- `source/` - All source content files (Markdown and HTML)
-  - `source/_layouts/` - Jekyll layout templates (main-page, default, 
core-developers, maven-archetypes)
-  - `source/_includes/` - Reusable HTML partials (header, footer)
-  - `source/.htaccess` - Redirect rules
-- `content/` - Generated output (not committed to git)
-- `_config.yml` - Jekyll configuration and site variables
-
-## Site Configuration
+## Architecture
 
-The `_config.yml` file contains important site-wide variables:
+### Directory Structure
 
-- `current_version` / `prev_version` - Struts version tracking
-- `release_date` / `prev_release_date` - Release date tracking
-- `archetype_version` - Maven archetype version
-- `repository_url` - GitHub repository for edit links
-- `apidocs` - Path to API documentation
-- `wiki_url` - Confluence wiki URL
-- `archive_url` - Archive distribution URL
-- `jira_url` - JIRA issue tracking URL
+- `source/` - All source content (Markdown/HTML), Jekyll source directory
+  - `_layouts/` - Page templates: `default`, `main-page`, `core-developers`, 
`maven-archetypes`
+  - `_includes/` - Shared partials: `header.html`, `footer.html`
+  - `_plugins/` - Custom Liquid tags (see below)
+  - `.htaccess` - Apache redirect rules (update when adding yearly 
announcement pages)
+- `_config.yml` - Jekyll config and site-wide version/release variables
+- `.asf.yaml` - ASF infrastructure config (deployment, notifications, branch 
protection)
 
-These variables are used throughout the site for dynamic content.
+### Content Sections
 
-## Content Guidelines
+The `source/` directory contains these main content areas:
+- `docs/` - Framework documentation
+- `getting-started/` - Getting started guides
+- `plugins/` - Plugin documentation
+- `core-developers/` - Core developer guide (uses `core-developers` layout)
+- `security/` - Security bulletins
+- `tag-developers/` - Tag developer documentation
+- `maven-archetypes/` - Maven archetype docs (uses `maven-archetypes` layout)
+- `announce-YYYY.md/html` - Yearly announcement pages
 
-### Page Front Matter
+### Site Variables in `_config.yml`
 
-All Markdown pages should start with YAML front matter:
-
-```yaml
----
-layout: default
-title: Page Title
----
-```
+Version and release date variables (`current_version`, `prev_version`, 
`release_date`, etc.) are referenced throughout `source/index.html`, 
`source/download.md`, and `source/releases.md` using `{{ site.variable_name 
}}`. When preparing a new release, update these in `_config.yml` rather than 
editing individual pages.
 
-Available layouts: `default`, `main-page`, `core-developers`, 
`maven-archetypes`
+### Custom Jekyll Plugins
 
-### Styling Classes
+Two custom Liquid tags in `source/_plugins/`:
 
-Use these Kramdown-style classes for formatting:
+- **`{% snippet %}`** - Fetches and embeds code snippets from remote sources 
(Apache Git repos). Supports parameters: `url=`, `id=` (for snippet markers), 
`lang=` (syntax highlighting), `javadoc=` (strip Javadoc formatting). Caches 
fetched content in `target/snippet_*.cache`.
+- **`{% remote_file_content %}`** - Fetches and inlines content from a remote 
URL.
 
-**Text alignment:** `{:.text-left}`, `{:.text-center}`, `{:.text-right}`, 
`{:.text-justify}`
+### Layouts
 
-**Text colors:** `{:.text-primary}`, `{:.text-info}`, `{:.text-success}`, 
`{:.text-warning}`, `{:.text-danger}`
+- `default` - Standard content page with "Edit on GitHub" link and optional 
parent breadcrumb
+- `main-page` - Homepage layout (no sidebar, no edit link)
+- `core-developers` - Like default but with hardcoded "back to Core Developers 
Guide" link
+- `maven-archetypes` - Similar to core-developers
 
-**Backgrounds:** `{:.bg-primary}`, `{:.bg-info}`, `{:.bg-success}`, 
`{:.bg-warning}`, `{:.bg-danger}`
+### Styling
 
-**Labels:** `{:.label .label-primary}`, etc.
+Kramdown attribute syntax for Bootstrap classes:
+- Alerts: `{:.alert .alert-warning}`, `{:.alert .alert-info}`, etc.
+- Text: `{:.text-primary}`, `{:.text-danger}`, etc.
+- See `source/updating-website.md` for complete examples.
 
-**Alert panels:** `{:.alert .alert-info}`, `{:.alert .alert-success}`, 
`{:.alert .alert-warning}`, `{:.alert .alert-danger}`
+## Deployment
 
-See `source/updating-website.md` for complete styling examples.
+### Branching
 
-## Deployment Process
-
-### Branching Strategy
-
-- `main` - Source branch for all changes and PRs
-- `asf-site` - Production site (auto-deployed, DO NOT MODIFY MANUALLY)
-- `asf-staging` - Staging site (auto-deployed, DO NOT MODIFY MANUALLY)
+- `main` - Source branch for all changes/PRs
+- `asf-site` - Production (auto-deployed, DO NOT MODIFY)
+- `asf-staging` - Staging (auto-deployed, DO NOT MODIFY)
 
 ### Workflow
 
-1. Make changes to the `main` branch
-2. Small changes: Push directly to `main` (for contributors)
-3. Larger changes: Open a Pull Request against `main`
-4. PRs are automatically built and deployed to the staging site: 
https://struts.staged.apache.org/
-5. After PR merge, changes are automatically built and deployed to production 
via buildbot
-
-### Build Infrastructure
-
-- `.asf.yaml` - Controls ASF infrastructure integration (notifications, JIRA 
linking, Jekyll deployment)
-- Buildbot job builds and deploys the main site
-- Jenkins job builds and deploys the staging site and JavaDocs
+1. Push changes to `main` or open a PR against `main`
+2. PRs auto-deploy to staging: https://struts.staged.apache.org/
+3. After merge, auto-deployed to production via buildbot
 
-### JavaDocs Deployment
+### Common Tasks
 
-JavaDocs are deployed via a dedicated Jenkins job. Provide the Git tag (e.g., 
`STRUTS_2_5_22`) to generate and deploy JavaDocs for a specific release.
+**New release**: Update version variables in `_config.yml`, add announcement 
entry to the current year's `announce-YYYY.md`.
 
-## Jekyll Configuration
+**New announcement year**: Create `source/announce-YYYY.md`, update the 
redirect in `source/.htaccess` (`RedirectMatch \/announce.html` line) to point 
to the new year.
 
-- Uses Kramdown markdown processor with GFM (GitHub Flavored Markdown) input
-- Syntax highlighting via Rouge
-- Auto-generates IDs for headings
-- Table of contents levels: 1-3
-- Source directory: `source/`
-- Encoding: UTF-8
\ No newline at end of file
+**New security bulletin**: Add to `source/security/` directory.
\ No newline at end of file
diff --git a/source/core-developers/action-file-upload-interceptor.md 
b/source/core-developers/action-file-upload-interceptor.md
index 06a67c55d..52e489e8b 100644
--- a/source/core-developers/action-file-upload-interceptor.md
+++ b/source/core-developers/action-file-upload-interceptor.md
@@ -37,13 +37,30 @@ You can override the text of these messages by providing 
text for the following
 ## Parameters
 
  - `maximumSize` (optional) - the maximum size (in bytes) that the interceptor 
will allow a file reference to be set
-   on the action. Note, this is <b>not</b> related to the various properties 
found in struts.properties. 
+   on the action. Note, this is <b>not</b> related to the various properties 
found in struts.properties.
    Default to approximately 2MB.
  - `allowedTypes` (optional) - a comma separated list of content types (ie: 
`text/html`) that the interceptor will allow
    a file reference to be set on the action. If none is specified allow all 
types to be uploaded.
  - `allowedExtensions` (optional) - a comma separated list of file extensions 
(ie: `.html`) that the interceptor will allow
    a file reference to be set on the action. If none is specified allow all 
extensions to be uploaded.
 
+### Dynamic Parameter Evaluation
+
+> Since Struts 7.2.0
+
+The `allowedTypes`, `allowedExtensions`, and `maximumSize` parameters support 
`${...}` expression evaluation,
+enabling per-request dynamic validation. This is available when used with 
`WithLazyParams`.
+
+```xml
+<interceptor-ref name="actionFileUpload">
+  <param name="allowedTypes">${allowedContentTypes}</param>
+  <param name="maximumSize">${maxFileSize}</param>
+</interceptor-ref>
+```
+
+The expressions are evaluated against the ValueStack at the time of the 
upload, allowing your action to provide
+dynamic values based on the current request context.
+
 ## Extending the Interceptor
 
 You can extend this interceptor and override the acceptFile method to provide 
more control over which files are supported 
diff --git a/source/core-developers/prepare-interceptor.md 
b/source/core-developers/prepare-interceptor.md
index c2e97c94e..40fcde2fb 100644
--- a/source/core-developers/prepare-interceptor.md
+++ b/source/core-developers/prepare-interceptor.md
@@ -29,9 +29,13 @@ on the actual object loaded from the database. See the 
example for more info.
 In `PrepareInterceptor` applies only when action implements `Preparable`
  1. if the action class have `prepare<MethodName>()`, it will be invoked
  2. else if the action class have `prepareDo<MethodName>()`, it will be invoked
- 3. no matter if 1] or 2] is performed, if `alwaysInvokePrepare` property of 
the interceptor is `true` (which is by 
+ 3. no matter if 1) or 2) is performed, if `alwaysInvokePrepare` property of 
the interceptor is `true` (which is by
    default `true`), `prepare()` will be invoked.
 
+> Note: since Struts 7.2.0, the `Preparable.prepare()` method is now a 
`default` method with an empty implementation.
+> Actions that only use per-method variants (e.g., `prepareEdit()`, 
`prepareSave()`) no longer need to provide
+> an empty `prepare()` override.
+
 ## Parameters
 
  - `alwaysInvokePrepare` - Default to true. If true, prepare will always be 
invoked, otherwise it will not.
diff --git a/source/core-developers/type-conversion.md 
b/source/core-developers/type-conversion.md
index 85b16bac2..f52d61ef6 100644
--- a/source/core-developers/type-conversion.md
+++ b/source/core-developers/type-conversion.md
@@ -114,14 +114,21 @@ amount=com.acme.converters.MyCustomBigDecimalConverter
 
 ## Applying a Type Converter for an application
 
-Application-wide converters can be specified in a file called 
`struts-conversion.properties` or `xwork-conversion.properties` (deprecated) 
+Application-wide converters can be specified in a file called 
`struts-conversion.properties` or `xwork-conversion.properties` (deprecated)
 located in the root of the classpath.
 
 ```
 # syntax: <type> = <converterClassName>
-java.math.BigDecimal = com.acme.MyBigDecimalConverter 
+java.math.BigDecimal = com.acme.MyBigDecimalConverter
 ```
 
+> NOTE: since Struts 7.2.0, when the Spring plugin is active, you can use 
Spring bean names in addition to fully qualified
+> class names as converter values in `struts-conversion.properties`. For 
example, if you have a Spring bean named
+> `myBigDecimalConverter`, you can reference it directly:
+> ```
+> java.math.BigDecimal = myBigDecimalConverter
+> ```
+
 ## A Simple Example
 
 Type conversion is great for situations where you need to turn a String in to 
a more complex object. Because the web
diff --git a/source/plugins/spring/index.md b/source/plugins/spring/index.md
index 3203a681d..e35f76934 100644
--- a/source/plugins/spring/index.md
+++ b/source/plugins/spring/index.md
@@ -228,6 +228,19 @@ so only actions are handled by it. This constant supports 
a comma separated list
 
 > This feature is experimental, and **should never** be used in production 
 > systems.
 
+## Migration Note: autowire alwaysRespect default change (7.2.0)
+
+Starting with Struts 7.2.0, the 
`struts.objectFactory.spring.autoWire.alwaysRespect` constant defaults to `true`
+(previously `false`). This means the configured autowire strategy is now 
always applied consistently, which fixes issues
+such as broken redirect URLs when Spring String beans are involved.
+{:.alert .alert-warning}
+
+If you experience unexpected behavior after upgrading to 7.2.0, you can 
restore the previous behavior by setting:
+
+```xml
+<constant name="struts.objectFactory.spring.autoWire.alwaysRespect" 
value="false" />
+```
+
 ## Settings
 
 The following settings can be customized. See the [developer 
guide](/core-developers/configuration-files).
@@ -235,7 +248,7 @@ The following settings can be customized. See the 
[developer guide](/core-develo
 |Setting|Description|Default|Possible Values|
 |-------|-----------|-------|---------------|
 |struts.objectFactory.spring.autoWire|The autowire 
strategy|name|name,type,auto, or constructor|
-|struts.objectFactory.spring.autoWire.alwaysRespect|Whether the autowire 
strategy should always be used, or if the framework should try to guess the 
best strategy based on the situation|false for backwards-compatibility|true or 
false|
+|struts.objectFactory.spring.autoWire.alwaysRespect|Whether the autowire 
strategy should always be used, or if the framework should try to guess the 
best strategy based on the situation|true (changed from false in 7.2.0)|true or 
false|
 |struts.objectFactory.spring.useClassCache|Whether to have Spring use its 
class cache or not|true|true or false|
 |struts.class.reloading.watchList|List of jar files or directories to watch 
for changes|null|Comma separated list of absolute or relative paths to jars or 
directories|
 |struts.class.reloading.acceptClasses|List of regular expressions of accepted 
class names|null|Comma separated list of regular expressions of classes that 
will be loaded by the reloading class loader(we suggest to add regular 
expressions so only action classes are handled by the reloading class loader)|
diff --git a/source/security/index.md b/source/security/index.md
index 19eff51bd..79ddd46e7 100644
--- a/source/security/index.md
+++ b/source/security/index.md
@@ -40,11 +40,14 @@ by security level.
 
 ### Never expose JSP files directly
 
-You must always hide JSP file behind an action, you cannot allow for direct 
access to the JSP files as this can leads 
-to unpredictable security vulnerabilities. You can achieve this by putting all 
your JSP files under the `WEB-INF` folder 
-- most of the JEE containers restrict access to files placed under the 
`WEB-INF` folder. Second option is to add security 
+You must always hide JSP file behind an action, you cannot allow for direct 
access to the JSP files as this can leads
+to unpredictable security vulnerabilities. You can achieve this by putting all 
your JSP files under the `WEB-INF` folder
+- most of the JEE containers restrict access to files placed under the 
`WEB-INF` folder. Second option is to add security
 constraint to the `web.xml` file:
 
+> Note: since Struts 7.2.0, the framework now logs a security warning when JSP 
tags are accessed directly outside of
+> an action scope. This helps identify JSP files that are inadvertently 
exposed without action protection.
+
 ```xml
 <!-- Restricts access to pure JSP files - access available only via Struts 
action -->
 <security-constraint>
diff --git a/source/tag-developers/checkbox-tag.md 
b/source/tag-developers/checkbox-tag.md
index 38426f42d..58f0b6ffa 100644
--- a/source/tag-developers/checkbox-tag.md
+++ b/source/tag-developers/checkbox-tag.md
@@ -39,3 +39,21 @@ Renders an HTML input element of type checkbox, populated by 
the specified prope
 ```html
 <input type="checkbox" name="checkboxField1" value="true" checked="checked" />
 ```
+
+## Hidden Field Prefix
+
+> Since Struts 7.2.0
+
+The checkbox tag generates a companion hidden field to ensure that unchecked 
values are still submitted with the form.
+By default, this hidden field uses the prefix `__checkbox_` (e.g., 
`__checkbox_checkboxField1`).
+
+For HTML5 compliance, you can change the prefix to `struts_checkbox_` using 
the `struts.ui.checkbox.hiddenPrefix` constant:
+
+```xml
+<constant name="struts.ui.checkbox.hiddenPrefix" value="struts_checkbox_" />
+```
+
+| Prefix | Example Hidden Field Name | Notes |
+|--------|--------------------------|-------|
+| `__checkbox_` | `__checkbox_checkboxField1` | Default, backward-compatible |
+| `struts_checkbox_` | `struts_checkbox_checkboxField1` | HTML5-compliant 
alternative |

Reply via email to