spring MVC之Annotated Controllers

概述

@PostMapping要与@RequestBody结合使用

摘自:spring MVC doc API

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 — intlongDate, 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 PropertyPlaceHolderConfigureragainst 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 requiredattribute — e.g. @RequestParam@RequestHeader, etc, and is equivalent to required=false.

Controller method argumentDescription

WebRequestNativeWebRequest

Generic access to request parameters, request & session attributes, without direct use of the Servlet API.

javax.servlet.ServletRequestjavax.servlet.ServletResponse

Choose any specific request or response type — e.g. ServletRequestHttpServletRequest, or Spring’s MultipartRequestMultipartHttpServletRequest.

javax.servlet.http.HttpSession

Enforces the presence of a session. As a consequence, such an argument is never null.
Note: Session access is not thread-safe. Consider setting theRequestMappingHandlerAdapter's "synchronizeOnSession" flag to "true" if multiple requests are allowed to access a session concurrently.

javax.servlet.http.PushBuilder

Servlet 4.0 push builder API for programmatic HTTP/2 resource pushes. Note that per Servlet spec, the injected PushBuilder instance can be null if the client does not support that HTTP/2 feature.

java.security.Principal

Currently authenticated user; possibly a specific Principal implementation class if known.

HttpMethod

The HTTP method of the request.

java.util.Locale

The current request locale, determined by the most specific LocaleResolveravailable, in effect, the configured LocaleResolver/LocaleContextResolver.

java.util.TimeZone + java.time.ZoneId

The time zone associated with the current request, as determined by a LocaleContextResolver.

java.io.InputStreamjava.io.Reader

For access to the raw request body as exposed by the Servlet API.

java.io.OutputStreamjava.io.Writer

For access to the raw response body as exposed by the Servlet API.

@PathVariable

For access to URI template variables. See URI patterns.

@MatrixVariable

For access to name-value pairs in URI path segments. See Matrix variables.

@RequestParam

For access to Servlet request parameters. Parameter values are converted to the declared method argument type. See @RequestParam.

Note that use of @RequestParam is optional, e.g. to set its attributes. See "Any other argument" further below in this table.

@RequestHeader

For access to request headers. Header values are converted to the declared method argument type. See @RequestHeader.

@CookieValue

For access to cookies. Cookies values are converted to the declared method argument type. See @CookieValue.

@RequestBody

For access to the HTTP request body. Body content is converted to the declared method argument type using HttpMessageConverters. See @RequestBody.

HttpEntity<B>

For access to request headers and body. The body is converted with HttpMessageConverters. See HttpEntity.

@RequestPart

For access to a part in a "multipart/form-data" request. See Multipart.

java.util.Maporg.springframework.ui.Modelorg.springframework.ui.ModelMap

For access to the model that is used in HTML controllers and exposed to templates as part of view rendering.

RedirectAttributes

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.

@ModelAttribute

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 @ModelAttribute is optional, e.g. to set its attributes. See "Any other argument" further below in this table.

ErrorsBindingResult

For access to errors from validation and data binding for a command object (i.e. @ModelAttribute argument), or errors from the validation of an @RequestBody or@RequestPart arguments; an Errors, or BindingResult argument must be declared immediately after the validated method argument.

SessionStatus + class-level @SessionAttributes

For marking form processing complete which triggers cleanup of session attributes declared through a class-level @SessionAttributes annotation. See@SessionAttributes for more details.

UriComponentsBuilder

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 Forwarded and X-Forwarded-* headers. See URI Links.

@SessionAttribute

For access to any session attribute; in contrast to model attributes stored in the session as a result of a class-level @SessionAttributes declaration. See@SessionAttribute for more details.

@RequestAttribute

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 @RequestParam if it is a simple type, as determined byBeanUtils#isSimpleProperty, or as an @ModelAttribute otherwise.

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 valueDescription

@ResponseBody

The return value is converted through HttpMessageConverters and written to the response. See @ResponseBody.

HttpEntity<B>ResponseEntity<B>

The return value specifies the full response including HTTP headers and body be converted through HttpMessageConverters and written to the response. See ResponseEntity.

HttpHeaders

For returning a response with headers and no body.

String

A view name to be resolved with ViewResolver's and used together with the implicit model — determined through command objects and @ModelAttribute methods. The handler method may also programmatically enrich the model by declaring a Model argument (see above).

View

View instance to use for rendering together with the implicit model — determined through command objects and @ModelAttribute methods. The handler method may also programmatically enrich the model by declaring a Model argument (see above).

java.util.Maporg.springframework.ui.Model

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.

void

A method with a void return type (or null return value) is considered to have fully handled the response if it also has a ServletResponse, or an OutputStream argument, or an @ResponseStatus annotation. The same is true also if the controller has made a positive ETag or lastModified timestamp check (see @Controller caching for details).

If none of the above is true, a void return type may also indicate "no response body" for REST controllers, or default view name selection for HTML controllers.

DeferredResult<V>

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 andDeferredResult.

Callable<V>

Produce any of the above return values asynchronously in a Spring MVC managed thread. See Async Requests and Callable.

ListenableFuture<V>,java.util.concurrent.CompletionStage<V>,java.util.concurrent.CompletableFuture<V>

Alternative to DeferredResult as a convenience for example when an underlying service returns one of those.

ResponseBodyEmitterSseEmitter

Emit a stream of objects asynchronously to be written to the response withHttpMessageConverter's; also supported as the body of a ResponseEntity. See Async Requests and HTTP Streaming.

StreamingResponseBody

Write to the response OutputStream asynchronously; also supported as the body of a ResponseEntity. See Async Requests and HTTP Streaming.

Reactive types — Reactor, RxJava, or others via ReactiveAdapterRegistry

Alternative to `DeferredResult with multi-value streams (e.g. FluxObservable) collected to a List.

For streaming scenarios — e.g. text/event-streamapplication/json+stream —  SseEmitter and ResponseBodyEmitter are used instead, where ServletOutputStream blocking I/O is performed on a Spring MVC managed thread and back pressure applied against the completion of each write.

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 String or void (default view name selection viaRequestToViewNameTranslator applies); or as a model attribute to be added to the model, unless it is a simple type, as determined byBeanUtils#isSimpleProperty in which case it remains unresolved.

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 intlongDate, etc. are supported. Type conversion can be customized through a WebDataBinder, see DataBinder, or by registering Formatters with the FormattingConversionService, see Spring Field Formatting.

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值