Spring Boot端点参数签名,在给定两个参数的情况下引发模棱两可的端点异常

时间:2019-07-02 14:59:36

标签: java spring spring-boot spring-restcontroller ambiguous

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

但是,该要求意味着可以将端点与foo或称为bobby的新参数一起使用。

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

因此,我选择了使端点过载并使用spring boot技巧使签名由请求参数决定。

像这样:

@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 Boot版本1.5.16.RELEASE

3 个答案:

答案 0 :(得分:2)

为什么不选择主要终点?

对于第一个,只需在其中添加其他参数

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

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

答案 1 :(得分:1)

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

只有一个端点带有两个请求参数,而不是两个端点来服务两个请求参数。您可以选择使它不是必需的。

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

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

答案 2 :(得分:0)

尝试使用异常处理程序

 @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);
    }