lukaszlenart opened a new pull request, #1939: URL: https://github.com/apache/struts/pull/1939
Fixes [WW-5704](https://issues.apache.org/jira/browse/WW-5704) ## Problem `RequiredFieldValidator` never sees the request; it inspects the bound property and fails only on null, an empty array or an empty collection. A primitive `int` behind a radio group, or a file property `prepare()` loaded from an existing entity, can therefore never fail server-side — while the browser's `required` still blocks an unselected group or an empty file input. A false reject, which the feature's governing rule forbids. ## Fix A radio or file input omits its parameter when left empty, so on such a submit the property keeps whatever it holds — and that is the value the page is rendering. So `required` is emitted only while the bound value is one the validator itself would reject: | render-time value | radio/file at render | server on empty submit | `required` | |---|---|---|---| | `null`, `[]`, empty collection | nothing selected | fails | emitted — sides agree | | primitive `0`, off-list value, `prepare()`-loaded file | nothing selected | **passes** | not emitted — the ticket's false reject | | in-list value | pre-checked | passes | not emitted — inert either way | - `HtmlConstraintProvider.constraintsFor` gains an `Object value` parameter (the tag's resolved `nameValue`); `UIBean` passes it through. Unreleased interface (`@since 7.4.0`), no deprecation. - `StrutsHtmlConstraintProvider.addRequiredField` asks the validator instance: `RequiredFieldValidator.isMissing(value)`, extracted from `validate` so the two cannot drift — the WW-5703 lesson. - `File` keeps the raw property instead of a `String` conversion, because OGNL renders a null property as `""` under that conversion, which would hide a missing attachment; no `file.ftl` in any theme reads `nameValue`. The raw lookup honours `struts.el.throwExceptionOnFailure`, and an `UploadedFilesAware` action has no property behind `<s:file name="upload"/>`, so `File` tolerates exactly that one failure (a broken expression still surfaces) — found by `/code-review`, pinned by two tests. Residual, documented on the site page: a property null on GET but populated only on POST is the one case this cannot see. ## Verification - `Html5ConstraintRenderingTest` now pushes `ConstraintAction` (the object whose validators run) and adds: `int`-backed radio renders no `required`; `prepare()`-loaded attachment renders no `required`; null attachment still does; a property-less file input renders under `throwExceptionOnFailure`; a broken expression still throws there. - `RequiredFieldValidatorTest.testIsMissingMatchesWhatValidateRejects` pins the predicate. - `mvn test -DskipAssembly -pl core` green. - Security review and `/code-review high` run; the review's one finding (the throw-on-failure regression) is fixed in the second commit. Docs: apache/struts-site PR updates `client-side-validation.md`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
