If more than one of the @(Method)Mapping
annotations are used, only one seems to be recognized.
Reproduction:
Put @GetMapping
and @PostMapping
together on a method of a controller:
@RestController
class AnyController {
@GetMapping("x")
@PostMapping("x")
fun x() = println("x")
}
If you now test the endpoint you see that GET /x
is mapped, but POST /x
is not (405 - Method Not Allowed).
Expectation:
The expectation is that both annotations are processed and both endpoints would be available.
At least there should be a warning that one is ignored.
Tested with:
Spring Boot 3.0.13 on Java 17.0.7
Workaround:
Use @RequestMapping(method = { ... })
.
Comment From: calliduslynx
@cdmatta Of course you're right from technical point of view. And the way how these things are "implemented" as a composed annotation is extremely elegant.
But from a Spring Boot (novice) users view I see these annotations in hundreds of tutorials and articles and if I use them combined they don't cause any problems (compile error, start error, log). One of them just don't work. And even for me (who uses Spring Boot every day for years) it was not clear.
And the comment you marked is not very obvious. I read it and did not know that @RequestMapping
is not repeatable. And even with this knowledge you have to think twice to realize that two @(Method)Mapping
annotations will not work.
Comment From: sbrannen
If more than one of the
@(Method)Mapping
annotations are used only one seems to be recognized.
That's correct. Spring looks for the first @RequestMapping
annotation present and uses that one. If multiple @RequestMapping
annotations are meta-present (i.e., used as meta-annotations like on @GetMapping
, etc.), the first one is used, and the rest are ignored.
In addition, please note that a locally declared @RequestMapping
annotation will always override/hide @GetMapping
, @PostMapping
, etc.
The expectation is that both annotations are processed and both endpoints would be available.
I don't think that would be a good idea, since each annotation could provide conflicting values for other annotation attributes in @RequestMapping
.
The only way to map multiple explicit methods is via @RequestMapping
-- for example, @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
.
At least there should be a warning that one is ignored.
We can definitely mention in the documentation that only a single @RequestMapping
, @GetMapping
, etc. is supported.
As for logging a warning, I'm not sure if we want to go that far; however, we'll discuss it within the team.
Comment From: sbrannen
Team Decision:
For Spring Framework 6.1.x
, we have decided to detect multiple @RequestMapping
declarations on a handler method and log a warning stating that only the first such annotation will be used. We may also update the documentation for the affected annotations to point out the current limitation.
For Spring Framework 6.2
, we would like to investigate the feasibility of supporting multiple @RequestMapping
annotations on a single controller method. See #32043.