在 Spring Boot 上過載 REST 控制器端點

banq發表於2021-12-29

一種特殊情況是需要相同的端點和方法,但具有不同的引數和不同的行為,例如

http://example.com/test?foo=bobby
http://example.com/test?bar=tables

現在處理這個問題的標準方法是讓一個端點帶有兩個可選引數:

@GetMapping("/endpoint")
public Response getStuff(@RequestParam(value = "foo", required = false) String foo, 
            @RequestParam(value = "bar", required = false) String bar) {
        
        if (foo != null)
            // do stuff for foo
        else if (bar != null)
            // do stuff for bar
}


但是,還有另一種方法。

@GetMapping(value = "/endpoint", params = { "foo" })
public Response getStuff(@RequestParam(value = "foo") String foo) {

        // do stuff for foo
}

@GetMapping("/endpoint", params = { "bar" })
public Response getStuff(@RequestParam(value = "bar") String bar) {

        // do stuff for bar
}


此功能提供了很大的靈活性,但它帶來了以下形式的風險:
www.example.com/endpoint?foo=bobby&bar=tables
這將導致 Spring boot 崩潰,因為它無法解析到 REST 控制器中的適當功能。
為了解決這個問題,可以使用其中一個端點作為預設值。附加引數將被忽略。

@GetMapping(value = "/endpoint", params = { "foo", "bar" })
public Response getStuff(@RequestParam(value = "foo") String foo
@RequestParam(value = "bar", required = false)) String bar {

        // do stuff for foo by default, ignore bar variable
}

@GetMapping("/endpoint", params = { "bar" })
public Response getStuff(@RequestParam(value = "bar") String bar) {

        // do stuff for bar
}


 

相關文章