【问题标题】:How can correct Ambiguous handler methods mapped?如何正确映射不明确的处理程序方法?
【发布时间】:2019-12-18 16:32:28
【问题描述】:

我正在学习 Spring Boot,我有这段代码:

@GetMapping(value = "test/produits/{prixLimit}")
public List<Product> testeDeRequetes(@PathVariable int prixLimit) {
    return productDao.findByPrixGreaterThan(400);
}

@GetMapping(value = "test/produits/{recherche}")
public List<Product> testeDeRequetes(@PathVariable String recherche) {
    return productDao.findByNameLike("%"+recherche+"%");
}

第一种方法是使用过滤器搜索。
第二种是无过滤搜索。

最后我有这个错误:

Ambiguous handler methods mapped for '/test/produits/300': {public java.util.List com.ecommerce.microcommerce.web.controller.ProductController.testeDeRequetes(int), public java.util.List com.ecommerce.microcommerce.web.controller.ProductController.testeDeRequetes(java.lang.String)}

【问题讨论】:

    标签: java rest spring-boot


    【解决方案1】:

    我认为基本上你的 API 是模棱两可的。作为消费者,相同的动词 + 路径会让我感到困惑。

    这也有点限制。例如,通过您的设置,您将阻止用户搜索“123”(可能是产品 ID 或 SKU)。

    prixLimitrecherche 参数似乎是产品资源上的过滤器/查询,因此将它们作为查询参数而不是路径传递更有意义:

    @GetMapping(value = "test/produits/")
    public List<Product> testeDeRequetes(@RequestParam(name = "prixLimit", required = false) Integer prixLimit,
                                         @RequestParam(name = "recherche", required = false) String recherche {
        // if prixLimit is not null
        //   return productDao.findByPrixGreaterThan(prixLimit);
        // else if recherche is not null
        //   return productDao.findByNameLike("%"+recherche+"%");
        // else
        //   return some meaningful default behavior such as all
        //   products, or return 400 to indicate a bad request
    }
    

    但如果使用路径是此 API 的必需部分,则有几个选项可以消除歧义:

    添加额外的路径元素

    @GetMapping(value = "test/produits/prixLimit/{prixLimit}")
    public List<Product> testeDeRequetes(@PathVariable int prixLimit) {
        return productDao.findByPrixGreaterThan(prixLimit);
    }
    
    @GetMapping(value = "test/produits/recherche/{recherche}")
    public List<Product> testeDeRequetes(@PathVariable String recherche) {
        return productDao.findByNameLike("%"+recherche+"%");
    }
    

    使用单一方法处理两者

    @GetMapping(value = "test/produits/{param}")
    public List<Product> testeDeRequetes(@PathVariable String param) {
        // if param is an int...
        //   return productDao.findByPrixGreaterThan(param);
        // else
        //   return productDao.findByNameLike("%"+param+"%");
    }
    

    在路径映射中使用正则表达式

    这仍然有点限制,因为两个正则表达式模式必须是互斥的,否则您将得到相同的重复映射异常:

    // This can only handle digits
    @GetMapping(value = "test/produits/{prixLimit:[0-9]+}")
    public List<Product> testeDeRequetes(@PathVariable int prixLimit) {
        return productDao.findByPrixGreaterThan(400);
    }
    
    // This can only handle characters
    @GetMapping(value = "test/produits/{recherche:[A-Za-z]+}")
    public List<Product> testeDeRequetes(@PathVariable String recherche) {
        return productDao.findByNameLike("%"+recherche+"%");
    }
    

    请注意,在这种情况下您不能搜索“abc123”。

    【讨论】:

      【解决方案2】:

      我想你可以使用正则表达式来区分这些方法。

      @GetMapping(value = "test/produits/{prixLimit:[\\d]+}")
      public List<Product> testeDeRequetes(@PathVariable int prixLimit) {
          return productDao.findByPrixGreaterThan(400);
      }
      
      @GetMapping(value = "test/produits/{recherche:[A-z]}")
      public List<Product> testeDeRequetes(@PathVariable String recherche) {
          return productDao.findByNameLike("%"+recherche+"%");
      }
      

      这是示例(第 4.3 节。@PathVariable 与 RegEx):

      https://www.baeldung.com/spring-requestmapping#3-pathvariable-with-regex

      【讨论】:

        【解决方案3】:

        可以使用正则表达式

          @GetMapping("/products/{id:[\\d]+}")
          public List<Product> (@PathVariable Long id){
          }
        
          @GetMapping("/products/{name:[a-zA-Z]+}")
          public List<Product> (@PathVariable String name){
        
          }
        

        【讨论】:

          猜你喜欢
          • 2022-01-05
          • 2021-01-22
          • 2014-07-30
          • 1970-01-01
          • 2017-11-16
          • 1970-01-01
          • 2015-12-05
          • 2020-01-31
          • 2018-07-31
          相关资源
          最近更新 更多