Skip to content

Commit

Permalink
Improve documentation on reading form data
Browse files Browse the repository at this point in the history
`@RequestParam` should be favored over `@RequestBody`
which can't always be used reliably due to how the Servlet
API behaves.

Closes gh-33409
  • Loading branch information
sdeleuze committed Sep 3, 2024
1 parent 3c28310 commit 83be0f2
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,48 @@ values for the same parameter name.
When an `@RequestParam` annotation is declared as a `Map<String, String>` or
`MultiValueMap<String, String>`, 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<String, String> 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, String>): 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
Expand Down

0 comments on commit 83be0f2

Please sign in to comment.