From 83be0f2dac2c0a32143972a497a3b663c5b12ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Tue, 3 Sep 2024 20:22:00 +0200 Subject: [PATCH] Improve documentation on reading form data `@RequestParam` should be favored over `@RequestBody` which can't always be used reliably due to how the Servlet API behaves. Closes gh-33409 --- .../ann-methods/requestbody.adoc | 4 ++ .../ann-methods/requestparam.adoc | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestbody.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestbody.adoc index 9cdc1e8fb073..e7b22db93b6d 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestbody.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestbody.adoc @@ -34,6 +34,10 @@ Kotlin:: You can use the xref:web/webmvc/mvc-config/message-converters.adoc[Message Converters] option of the xref:web/webmvc/mvc-config.adoc[MVC Config] to configure or customize message conversion. +NOTE: Form data should be read using xref:web/webmvc/mvc-controller/ann-methods/requestparam.adoc[`@RequestParam`], +not with `@RequestBody` which can't always be used reliably since in the Servlet API, request parameter +access causes the request body to be parsed, and it can't be read again. + You can use `@RequestBody` in combination with `jakarta.validation.Valid` or Spring's `@Validated` annotation, both of which cause Standard Bean Validation to be applied. By default, validation errors cause a `MethodArgumentNotValidException`, which is turned diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc index 3486beeb3b07..5487d31368c5 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-methods/requestparam.adoc @@ -72,6 +72,48 @@ values for the same parameter name. When an `@RequestParam` annotation is declared as a `Map` or `MultiValueMap`, without a parameter name specified in the annotation, then the map is populated with the request parameter values for each given parameter name. +The following example shows how to do so with form data processing: + +[tabs] +====== +Java:: ++ +[source,java,indent=0,subs="verbatim,quotes",role="primary"] +---- + @Controller + @RequestMapping("/pets") + class EditPetForm { + + // ... + + @PostMapping(value = "/process", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public String processForm(@RequestParam MultiValueMap params) { + // ... + } + + // ... + } +---- +Kotlin:: ++ +[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] +---- + @Controller + @RequestMapping("/pets") + class EditPetForm { + + // ... + + @PostMapping("/process", consumes = [MediaType.APPLICATION_FORM_URLENCODED_VALUE]) + fun processForm(@RequestParam params: MultiValueMap): String { + // ... + } + + // ... + + } +---- +====== Note that use of `@RequestParam` is optional (for example, to set its attributes). By default, any argument that is a simple value type (as determined by