最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Handling optional parameters for @GetMapping("") in Spring fails RestAssured tests - Stack Overflow

programmeradmin1浏览0评论

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

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

Share Improve this question edited Nov 21, 2024 at 14:16 Robin Sving asked Nov 19, 2024 at 12:57 Robin SvingRobin Sving 3,4201 gold badge14 silver badges10 bronze badges 5
  • Apparently you are using Kotlin, now I wonder have you compiled your code with parameter retention? – M. Deinum Commented Nov 19, 2024 at 13:00
  • When using @GetMapping("/") I can match the name parameter, so I would guess that means that the parameter is retained properly – Robin Sving Commented Nov 19, 2024 at 13:26
  • That comment was also not really useful in hindsight, as you explictly added the name to the @RequestMapping. However using a / or not will lead to a different path as /hello and /hello/ are different paths and mappings. – M. Deinum Commented Nov 19, 2024 at 13:31
  • 1 I've created a sample Spring Boot project with Spring Web using Spring Initializr, in Kotlin, Java 21 and Spring Boot 3.3.5. I've added the exact code from your question, and it works. When I call http://localhost:8080/hello?name=banana, I've got a successful 200 response with hello banana as body. The error you mention suggests that somewhere you've got a @Controller or @ControllerAdvice that have intercepted your request, as it mentions resource fetching. Have you checked that you do not have such annotated components ? – amanin Commented Nov 20, 2024 at 17:20
  • The issue I am having is that it is failing my tests, and indeed it seems like the issue is not the setup, but that RestAssured cannot handle the request being empty. Will add a "solution" to the question and close it. Thanks for the comment! – Robin Sving Commented Nov 21, 2024 at 14:08
Add a comment  | 

1 Answer 1

Reset to default 1

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

发布评论

评论列表(0)

  1. 暂无评论