I have a Spring Boot application where I am using @RequestMapping at the class level and @GetMapping at the method level. Here is a highly simplified version of my controller:
@RestController
@RequestMapping("/hello")
class HelloController {
@GetMapping("")
fun test(@RequestParam("name", required = false) name: String?): String {
return "hello " + (name ?: "world")
}
}
When I call /hello
without name
, it works fine and returns "hello world".
However, when I call /hello?name=banana
, it does not work as expected, giving me the following error:
No static resource hello.
I have tried using @GetMapping("/")
instead of @GetMapping("")
, but that does not allow me to call /hello
without adding the optional parameters (i.e. works with ?name=batman
). Is there a way to handle both cases (with and without the request parameter) correctly in Spring Boot?
Additional info: This is a regression failure, from an upgrade of Java from 17 to 21 and Spring Boot from 2.7.5 to 3.2.5. This used to work before this upgrade.
I have noted that the Spring Boot instructions state that
@RequestMapping cannot be used in conjunction with other @RequestMapping annotations that are declared on the same element (class, interface, or method). If multiple @RequestMapping annotations are detected on the same element, a warning will be logged, and only the first mapping will be used. This also applies to composed @RequestMapping annotations such as @GetMapping, @PostMapping, etc
But I am not sure how to avoid it for my use-case
After some investigation I have found that the issue was not present in other places than my tests using RestAssured with an empty endpoint.
These were my tests originally
RestAssured.given().basePath("myapi/hello").`when`().get("") //<- succeeded
RestAssured.given().basePath("myapi/hello").`when`().get("?name=banana") //<- failed
After changing the tests this is the result
RestAssured.given().basePath("myapi").`when`().get("/hello") //<- succeeded
RestAssured.given().basePath("myapi").`when`().get("/hello?name=banana") //<- succeeded
Notably, this worked before upgrading to RestAssured 5.3.2, but not after