Log warning if multiple @⁠RequestMapping annotations are declared

If multiple request mapping annotations are discovered, Spring MVC and
Spring WebFlux now log a warning similar to the following (without
newlines).

Multiple @⁠RequestMapping annotations found on
void org.example.MyController.put(), but only the first will be used:
[
@⁠org.springframework.web.bind.annotation.PutMapping(consumes={}, headers={}, name="", params={}, path={"/put"}, produces={}, value={"/put"}),
@⁠org.springframework.web.bind.annotation.PostMapping(consumes={}, headers={}, name="", params={}, path={"/put"}, produces={}, value={"/put"})
]

Closes gh-31962
This commit is contained in:
Sam Brannen
2024-01-17 17:44:38 +01:00
parent 5bf74cae11
commit 699da7c383
12 changed files with 191 additions and 17 deletions

View File

@@ -40,7 +40,6 @@ import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@@ -363,7 +362,9 @@ class RequestMappingHandlerMappingTests {
@Controller
// gh-31962: The presence of multiple @RequestMappings is intentional.
@RequestMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@ExtraRequestMapping
static class ComposedAnnotationController {
@RequestMapping
@@ -382,7 +383,10 @@ class RequestMappingHandlerMappingTests {
public void post(@RequestBody(required = false) Foo foo) {
}
@PutMapping("/put")
// gh-31962: The presence of multiple @RequestMappings is intentional.
@PatchMapping("/put")
@RequestMapping(path = "/put", method = RequestMethod.PUT) // local @RequestMapping overrides meta-annotations
@PostMapping("/put")
public void put() {
}
@@ -396,6 +400,11 @@ class RequestMappingHandlerMappingTests {
}
@RequestMapping
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ExtraRequestMapping {
}
@RequestMapping(method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE,