概述
@PostMapping要与@RequestBody结合使用
1.4. Annotated Controllers
Spring MVC provides an annotation-based programming model where @Controller
and @RestController
components use annotations to express request mappings, request input, exception handling, and more. Annotated controllers have flexible method signatures and do not have to extend base classes nor implement specific interfaces.
@Controller
public class HelloController {
@GetMapping("/hello")
public String handle(Model model) {
model.addAttribute("message", "Hello World!");
return "index";
}
}
In this particular example the method accepts a Model
and returns a view name as a String
but many other options exist and are explained further below in this chapter.
1.4.1. Declaration
You can define controller beans using a standard Spring bean definition in the Servlet’s WebApplicationContext
. The @Controller
stereotype allows for auto-detection, aligned with Spring general support for detecting @Component
classes in the classpath and auto-registering bean definitions for them. It also acts as a stereotype for the annotated class, indicating its role as a web component.
To enable auto-detection of such @Controller
beans, you can add component scanning to your Java configuration:
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {
// ...
}
The XML configuration equivalent:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example.web"/>
<!-- ... -->
</beans>
@RestController
is a composed annotation that is itself meta-annotated with @Controller
and @ResponseBody
indicating a controller whose every method inherits the type-level @ResponseBody
annotation and therefore writes directly to the response body vs view resolution and rendering with an HTML template.
1.4.2. Request Mapping
The @RequestMapping
annotation is used to map requests to controllers methods. It has various attributes to match by URL, HTTP method, request parameters, headers, and media types. It can be used at the class-level to express shared mappings or at the method level to narrow down to a specific endpoint mapping.
There are also HTTP method specific shortcut variants of @RequestMapping
:
-
@GetMapping
-
@PostMapping
-
@PutMapping
-
@DeleteMapping
-
@PatchMapping
The above are Custom Annotations that are provided out of the box because arguably most controller methods should be mapped to a specific HTTP method vs using @RequestMapping
which by default matches to all HTTP methods. At the same an@RequestMapping
is still needed at the class level to express shared mappings.
Below is an example with type and method level mappings:
@RestController
@RequestMapping("/persons")
class PersonController {
@GetMapping("/{id}")
public Person getPerson(@PathVariable Long id) {
// ...
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void add(@RequestBody Person person) {
// ...
}
}
URI patterns
You can map requests using glob patterns and wildcards:
-
?
matches one character -
*
matches zero or more characters within a path segment -
**
match zero or more path segments
You can also declare URI variables and access their values with @PathVariable
:
@GetMapping("/owners/{ownerId}/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
URI variables can be declared at the class and method level:
@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {
@GetMapping("/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
// ...
}
}
URI variables are automatically converted to the appropriate type or`TypeMismatchException` is raised. Simple types — int
, long
, Date
, are supported by default and you can register support for any other data type. See Type Conversion and DataBinder.
URI variables can be named explicitly — e.g. @PathVariable("customId")
, but you can leave that detail out if the names are the same and your code is compiled with debugging information or with the -parameters
compiler flag on Java 8.
The syntax {varName:regex}
declares a URI variable with a regular expressions with the syntax {varName:regex}
— e.g. given URL "/spring-web-3.0.5 .jar"
, the below method extracts the name, version, and file extension:
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String ext) {
// ...
}
URI path patterns can also have embedded ${…}
placeholders that are resolved on startup via PropertyPlaceHolderConfigurer
against local, system, environment, and other property sources. This can be used for example to parameterize a base URL based on some external configuration.
1.4.3. Handler Methods
@RequestMapping
handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values.
Method Arguments
The table below shows supported controller method arguments. Reactive types are not supported for any arguments.
JDK 8’s java.util.Optional
is supported as a method argument in combination with annotations that have a required
attribute — e.g. @RequestParam
, @RequestHeader
, etc, and is equivalent to required=false
.
Controller method argument | Description |
---|---|
| Generic access to request parameters, request & session attributes, without direct use of the Servlet API. |
| Choose any specific request or response type — e.g. |
| Enforces the presence of a session. As a consequence, such an argument is never |
| Servlet 4.0 push builder API for programmatic HTTP/2 resource pushes. Note that per Servlet spec, the injected |
| Currently authenticated user; possibly a specific |
| The HTTP method of the request. |
| The current request locale, determined by the most specific |
| The time zone associated with the current request, as determined by a |
| For access to the raw request body as exposed by the Servlet API. |
| For access to the raw response body as exposed by the Servlet API. |
| For access to URI template variables. See URI patterns. |
| For access to name-value pairs in URI path segments. See Matrix variables. |
| For access to Servlet request parameters. Parameter values are converted to the declared method argument type. See @RequestParam. Note that use of |
| For access to request headers. Header values are converted to the declared method argument type. See @RequestHeader. |
| For access to cookies. Cookies values are converted to the declared method argument type. See @CookieValue. |
| For access to the HTTP request body. Body content is converted to the declared method argument type using |
| For access to request headers and body. The body is converted with |
| For access to a part in a "multipart/form-data" request. See Multipart. |
| For access to the model that is used in HTML controllers and exposed to templates as part of view rendering. |
| Specify attributes to use in case of a redirect — i.e. to be appended to the query string, and/or flash attributes to be stored temporarily until the request after redirect. See Redirect attributes and Flash attributes. |
| For access to an existing attribute in the model (instantiated if not present) with data binding and validation applied. See @ModelAttribute as well as Model and DataBinder. Note that use of |
| For access to errors from validation and data binding for a command object (i.e. |
| For marking form processing complete which triggers cleanup of session attributes declared through a class-level |
| For preparing a URL relative to the current request’s host, port, scheme, context path, and the literal part of the servlet mapping also taking into account |
| For access to any session attribute; in contrast to model attributes stored in the session as a result of a class-level |
| For access to request attributes. See @RequestAttribute for more details. |
Any other argument | If a method argument is not matched to any of the above, by default it is resolved as an |
Return Values
The table below shows supported controller method return values. Reactive types are supported for all return values, see below for more details.
Controller method return value | Description |
---|---|
| The return value is converted through |
| The return value specifies the full response including HTTP headers and body be converted through |
| For returning a response with headers and no body. |
| A view name to be resolved with |
| A |
| Attributes to be added to the implicit model with the view name implicitly determined through a |
| An attribute to be added to the model with the view name implicitly determined through a Note that |
| The view and model attributes to use, and optionally a response status. |
| A method with a If none of the above is true, a |
| Produce any of the above return values asynchronously from any thread — e.g. possibly as a result of some event or callback. See Async Requests and |
| Produce any of the above return values asynchronously in a Spring MVC managed thread. See Async Requests and |
| Alternative to |
| Emit a stream of objects asynchronously to be written to the response with |
| Write to the response |
Reactive types — Reactor, RxJava, or others via | Alternative to For streaming scenarios — e.g. See Async Requests and Reactive types. |
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 |
Type Conversion
Some annotated controller method arguments that represent String-based request input — e.g. @RequestParam
, @RequestHeader
, @PathVariable
, @MatrixVariable
, and @CookieValue
, may require type conversion if the argument is declared as something other than String
.
For such cases type conversion is automatically applied based on the configured converters. By default simple types such as int
, long
, Date
, etc. are supported. Type conversion can be customized through a WebDataBinder
, see DataBinder, or by registering Formatters
with the FormattingConversionService
, see Spring Field Formatting.