如何映射正确的不明确处理程序方法?



我正在学习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)}

我认为从根本上说你的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"。

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

@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

可以使用正则表达式

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

最新更新