Spring 启动端点参数签名,在给定两个参数时抛出不明确的端点异常

Spring boot endpoint parameter signature, is throwing ambiguous endpoint exception when both parameters are given

由于过去的设计方式,在这种情况下,为名为 foo 的特定参数创建了一个端点。

然而,该要求意味着端点可以与 foo 或名为 bobby 的新参数一起使用。

在尝试合并到一个端点后,重构工作太多了。

所以我选择重载端点并使用 spring 引导技巧让签名由请求参数决定。

像这样:

@GetMapping(params = {"foo"})
    public CollectionResource<FooResource> get(@RequestParam("foo") String foo, ...) {} ...

@GetMapping(params = {"bobby"})
    public CollectionResource<FooResource> get(@RequestParam("bobby") {} ...

这在像这样与端点交互时效果很好:

localhost:8080/testEndpoint?foo=bar

localhost:8080/testEndpoint?bobby=tables

但是我在尝试以下操作时发现了一个边缘案例:

localhost:8080/testEndpoint?bobby=tables&foo=bar

抛出以下运行时异常

java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8080/testEndpoint/':

此端点不是由用户访问的,而是通过编程方式访问的,因此这种情况发生的可能性很小。然而,有没有一种方法可以设置控制器,使其能够处理这个问题,并抛出 BadRequest 等而不是崩溃?

Spring 引导版本 : 1.5.16.RELEASE

为什么不选择主要终点?

对于第一个,只需添加附加参数即可

 public CollectionResource<FooResource> get(@RequestParam("foo") String foo, ...
  ,@RequestParam("bobby")) {

在这种特殊情况下将选择第一个端点

尝试使用异常处理程序

 @ExceptionHandler(Exception.class)
    public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
        List<String> details = new ArrayList<>();
        details.add(ex.getLocalizedMessage());
        ErrorResponse error = new ErrorResponse("Server Error", details);
        return new ResponseEntity(error, HttpStatus.BAD_REQUEST);
    }

Spring无法根据请求参数区分端点。

不是为两个请求参数提供服务的两个端点,而是只有一个端点和两个请求参数。您可以选择将其设为不需要。

@RequestParam("foo") String foo required = false, @RequestParam("bobby") String foo required = false

这为您提供了更简单的方法来处理 API