M05 Q05 How is an incoming request mapped to a controller and mapped to a method?
Incoming request is mapped to a controller and a method by DispatcherServlet
, which uses HandlerMapping
and HandlerAdapter
components for this purpose.
HandlerMapping
components are used during Spring initialization to scan classpath for @Controller
or @RestController
classes with one of request mapping annotations that are part of annotation-based programming model:
- @RequestMapping
- @GetMapping
- @PostMapping
- @PutMapping
- @PatchMapping
- @DeleteMapping
HandlerAdapter
components are responsible for execution of method identified as handler candidate for the request.
Now let's look at the lifecycle of the request when it is being created against the server. When request is performed against the server following steps are executed:
- Application Server (Standalone or Embedded) searches for Servlet that can handle request,
DispatcherServlet
is selected based on Servlet Registration and url-pattern. DispatcherServlet
usesHandlerMapping
classes to get request mapping information andHandlerAdapter
.DispatcherServlet
usesHandlerAdapter
to execute controller method that will handle request.DispatcherServlet
interprets results of method execution and rendersView
with help ofViewResolver
classes.
@RequestMapping
allows you to specify conditions that request has to match for a method to be used as request handler. @RequestMapping
can be used at class or method level, when used at the class level, all method level mappings inherit this primary mapping, narrowing it to a specific handler method.
For example, below controllers are supposed to map GET /say/hello
requests, even though request mapping is defined differently, all are equal.
@RequestMapping
annotation allows you to specify following criteria for request:
path
- uri path/paths for request, for example/api/books
method
โ supported HTTP method/methods:GET
,POST
,HEAD
,OPTIONS
,PUT
,PATCH
,DELETE
,TRACE
params
โ required parameters of request, for examplekey1=value1
,key2!=value2
,key1
,!key1
headers
โ header needs to match specified condition, for example,header1=value1
,header2!=value2
,header1
,!header1
,content-type=text/*
consumes
โ media types that can be consumed by request, for example,application/json
produces
โ media types that are produced by method handling the request, for example,application/pdf
Spring MVC also supports composed annotations for request mapping:
- @GetMapping
- @PostMapping
- @PutMapping
- @PatchMapping
- @DeleteMapping
Each of those annotations allows you to specify same conditions as @RequestMapping
except for HTTP method field, following fields in @*Mapping
are aliases to @RequestMapping: path, params, headers, consumes, produces
.
In most of the cases it is possible to translate mappings between those annotations, one example when this is not possible is when creating HTTP HEAD request mapping.
More examples
This index()
method has several uri to reach the index page
The second example is a header request.
The next example allows you to specify HTTP POST request and it allows you to search for the article based on some specified criteria.
And one more, the method to delete the article by id.