@ -1061,7 +1072,14 @@ programmatically enrich the model by declaring a `Model` argument (see above).
@@ -1061,7 +1072,14 @@ programmatically enrich the model by declaring a `Model` argument (see above).
|`java.util.Map`, `org.springframework.ui.Model`
|Attributes to be added to the implicit model with the view name implicitly determined
from the request path.
based on the request path.
|`@ModelAttribute`
|An attribute to be added to the model with the view name implicitly determined based
on the request path.
Note that `@ModelAttribute` is optional. See "Any other return value" further below in
this table.
|`Rendering`
|An API for model and view rendering scenarios.
@ -1081,11 +1099,12 @@ REST controllers, or default view name selection for HTML controllers.
@@ -1081,11 +1099,12 @@ REST controllers, or default view name selection for HTML controllers.
to be written (however `text/event-stream` must be requested or declared in the mapping
through the produces attribute).
|Any other return type
|A single model attribute to be added to the implicit model with the view name implicitly
determined through a `RequestToViewNameTranslator`; the attribute name may be specified
through a method-level `@ModelAttribute` or otherwise a name is selected based on the
class name of the return type.
|Any other return value
|If a return value is not matched to any of the above, by default it is treated as a view
name, if it is `String` or `void` (default view name selection applies); or as a model
attribute to be added to the model, unless it is a simple type, as determined by
@ -1145,6 +1164,12 @@ When an `@RequestParam` annotation is declared as `Map<String, String>` or
@@ -1145,6 +1164,12 @@ When an `@RequestParam` annotation is declared as `Map<String, String>` or
`MultiValueMap<String, String>` argument, the map is populated with all request
parameters.
Note that use of `@RequestParam` is optional, e.g. to set its attributes.
By default any argument that is a simple value type, as determined by
and is not resolved by any other argument resolver, is treated as if it was annotated
with `@RequestParam`.
[[webflux-ann-requestheader]]
==== @RequestHeader
@ -1231,7 +1256,7 @@ Type conversion is applied automatically if the target method parameter type is
@@ -1231,7 +1256,7 @@ Type conversion is applied automatically if the target method parameter type is
Use the `@ModelAttribute` annotation on a method argument to access an attribute from the
model, or have it instantiated if not present. The model attribute is also overlaid with
values query parameters for form fields whose names match to field names. This is
values of query parameters and form fields whose names match to field names. This is
referred to as data binding and it saves you from having to deal with parsing and
converting individual query parameters and form fields. For example:
and is not resolved by any other argument resolver, is treated as if it was annotated
with `@ModelAttribute`.
[[webflux-ann-sessionattributes]]
==== @SessionAttributes
@ -1374,7 +1405,7 @@ use the `@SessionAttribute` annotation on a method parameter:
@@ -1374,7 +1405,7 @@ use the `@SessionAttribute` annotation on a method parameter:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@RequestMapping("/")
@GetMapping("/")
public String handle(**@SessionAttribute** User user) {
// ...
}
@ -1388,6 +1419,23 @@ workflow consider using `SessionAttributes` as described in
@@ -1388,6 +1419,23 @@ workflow consider using `SessionAttributes` as described in
<<webflux-ann-sessionattributes>>.
[[webflux-ann-requestattrib]]
==== @RequestAttribute
[.small]#<<web.adoc#mvc-ann-requestattrib,Same in Spring MVC>>#
Similar to `@SessionAttribute` the `@RequestAttribute` annotation can be used to
access pre-existing request attributes created earlier, e.g. by a `WebFilter`:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@GetMapping("/")
public String handle(**@RequestAttribute** Client client) {
@ -1691,6 +1691,13 @@ programmatically enrich the model by declaring a `Model` argument (see above).
@@ -1691,6 +1691,13 @@ programmatically enrich the model by declaring a `Model` argument (see above).
|Attributes to be added to the implicit model with the view name implicitly determined
through a `RequestToViewNameTranslator`.
|`@ModelAttribute`
|An attribute to be added to the model with the view name implicitly determined through
a `RequestToViewNameTranslator`.
Note that `@ModelAttribute` is optional. See "Any other return value" further below in
this table.
|`ModelAndView` object
|The view and model attributes to use, and optionally a response status.
@ -1735,11 +1742,13 @@ completion of each write.
@@ -1735,11 +1742,13 @@ completion of each write.
See <<mvc-ann-async-reactive-types>>.
|Any other return type
|A single model attribute to be added to the implicit model with the view name implicitly
determined through a `RequestToViewNameTranslator`; the attribute name may be specified
through a method-level `@ModelAttribute` or otherwise a name is selected based on the
class name of the return type.
|Any other return value
|If a return value is not matched to any of the above, by default it is treated as a view
name, if it is `String` or `void` (default view name selection via
`RequestToViewNameTranslator` applies); or as a model attribute to be added to the model,
@ -1799,6 +1808,12 @@ When an `@RequestParam` annotation is declared as `Map<String, String>` or
@@ -1799,6 +1808,12 @@ When an `@RequestParam` annotation is declared as `Map<String, String>` or
`MultiValueMap<String, String>` argument, the map is populated with all request
parameters.
Note that use of `@RequestParam` is optional, e.g. to set its attributes.
By default any argument that is a simple value type, as determined by
and is not resolved by any other argument resolver, is treated as if it was annotated
with `@RequestParam`.
[[mvc-ann-requestheader]]
==== @RequestHeader
@ -1985,84 +2000,12 @@ Validation can be applied automatically after data binding by adding the
@@ -1985,84 +2000,12 @@ Validation can be applied automatically after data binding by adding the
}
----
Note that use of `@ModelAttribute` is optional, e.g. to set its attributes.
By default any argument that is not a simple value type, as determined by
The next step is to create a controller that handles the file upload. This controller is
very similar to a <<mvc-ann-controller,normal annotated `@Controller`>>, except that we
use `MultipartHttpServletRequest` or `MultipartFile` in the method parameters:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
----
Note how the `@RequestParam` method parameters map to the input elements declared in the
form. In this example, nothing is done with the `byte[]`, but in practice you can save
it in a database, store it on the file system, and so on.
When using Servlet 3.0 multipart parsing you can also use `javax.servlet.http.Part` for
the method parameter:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") Part file) {
InputStream inputStream = file.getInputStream();
// store bytes from uploaded file somewhere
return "redirect:uploadSuccess";
}
}
----
[[mvc-ann-sessionattributes]]
@ -2142,14 +2085,16 @@ workflow consider using `SessionAttributes` as described in
@@ -2142,14 +2085,16 @@ workflow consider using `SessionAttributes` as described in
[[mvc-ann-requestattrib]]
==== @RequestAttribute
[.small]#<<web-reactive.adoc#webflux-ann-requestattrib,Same in Spring WebFlux>>#
Similar to `@SessionAttribute` the `@RequestAttribute` annotation can be used to
access pre-existing request attributes created by a filter or interceptor:
access pre-existing request attributes created earlier, e.g. by a Servlet `Filter`
or `HandlerInterceptor`:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@RequestMapping("/")
@GetMapping("/")
public String handle(**@RequestAttribute** Client client) {
// ...
}
@ -2245,14 +2190,79 @@ Therefore the use of flash attributes is recommended mainly for redirect scenari
@@ -2245,14 +2190,79 @@ Therefore the use of flash attributes is recommended mainly for redirect scenari
****
[[mvc-multipart-forms-non-browsers]]
==== @RequestPart
[[mvc-multipart-forms]]
==== Multipart
After a `MultipartResolver` has been <<mvc-multipart,enabled>>, the content of POST
requests with "multipart/form-data" is parsed and accessible as regular request
parameters. In the example below we access one regular form field and one uploaded
file:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
byte[] bytes = file.getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
----
[NOTE]
====
When using Servlet 3.0 multipart parsing you can also use `javax.servlet.http.Part` as
a method argument instead of Spring's `MultipartFile`.
====
Multipart content can also be used as part of data binding to a
<<mvc-ann-modelattrib-method-args,command object>>. For example the above form field
and file could have been fields on a form object:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
class MyForm {
private String name;
private MultipartFile file;
// ...
}
@Controller
public class FileUploadController {
@PostMapping("/form")
public String handleFormUpload(MyForm form, BindingResult errors) {
if (!form.getFile().isEmpty()) {
byte[] bytes = form.getFile().getBytes();
// store the bytes somewhere
return "redirect:uploadSuccess";
}
return "redirect:uploadFailure";
}
}
----
Multipart requests can also be submitted from non-browser clients in a RESTful service
scenario. All of the above examples and configuration apply here as well. However,
unlike browsers that typically submit files and simple form fields, a programmatic
client can also send more complex data of a specific content type -- for example a
multipart request with a file and second part with JSON formatted data:
scenario with more types of content. For example a file along with JSON: