【问题标题】:Spring RestController - findById and findByEmail request method not working (Ambiguous handler)Spring RestController - findById 和 findByEmail 请求方法不起作用(不明确的处理程序)
【发布时间】:2018-07-04 19:54:14
【问题描述】:

我想根据 ID 或电子邮件检索 user 的信息。下面是我写的控制器类:

@RestController
@RequestMapping("/users")
public class UserController {

    @Autowired
    private UserDao userDao;
    
    @GetMapping(value = "/{id:\\d+}")
    public User findOneById(@PathVariable("id") final Integer userId) {
        return userDao.findById(userId).get();
    }
    
    @GetMapping(value = "/{email}")
    public User findOneByEmail(@PathVariable("email") final String email) {
        return userDao.findByEmail(email).get();
    }     

代码不工作并给出错误
java.lang.IllegalStateException:映射到 HTTP 路径“http://localhost:8080/users/12223”的不明确处理程序方法:{public com.example. persistence.model.User com.example.rest.controller.UserController.findOneById(java.lang.Integer), public com.example.persistence.model.User com.example.rest.controller.UserController.findOneByEmail(java.lang.字符串)}。

我认为 Regex 可以解决这个问题,但不幸的是它没有。
我理解错误的原因,但是处理这种要求的方法是什么?

【问题讨论】:

  • 使其明确:指定一个应该与 findByEmail 匹配的正则表达式。

标签: spring spring-mvc spring-boot spring-data-rest


【解决方案1】:

您的问题是http://localhost:8080/users/12223 匹配/users/{id:\\d+}/users/{email}。 12223 是两种方法的有效参数:

  • 12223 匹配 {id:\\d+},因为它包含所有数字
  • 12223 匹配{email},因为没有指定正则表达式,任何参数都将匹配电子邮件。

Spring 无法选择适当的端点并给出错误:为 HTTP 路径映射的不明确的处理程序方法。

如果您尝试另一个参数,例如:http://localhost:8080/users/somebody@example.com,则不会出现错误。 Spring 将能够发现,someone@example.com 不匹配 id 并且匹配 email

正如 JB Nizet 在 cmets 中提到的,您有两种方法可以解决这个问题:

  1. 为电子邮件指定正则表达式以匹配电子邮件格式,例如{email:.+@.+\..+}
  2. 明确推荐 pDer666 等端点:

    @GetMapping(value = "/email/{email}")

    @GetMapping(value = "/id/{id:\d+}")

【讨论】:

    【解决方案2】:

    有不同的方法来解决这个问题。可以提供两个具有不同路径的 GetMapping,或者您只在一个 get 请求中使用查询参数。如果设置了电子邮件,则通过电子邮件检索数据 如果设置了另一个,则通过其他参数检索它。使用此解决方案,您可以轻松添加更多参数进行搜索,并且可以通过 OR 或 AND 查询数据,而无需添加新的控制器方法。

    网址:http://localhost:8080/users?email=asdf@somewhere.comhttp://localhost:8080/users?id=1234

    @GetMapping
    @ResponseBody
    public String findOne(@RequestParam("id") long id, @RequestParam("email") String email) {
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2020-01-05
      • 1970-01-01
      • 2017-11-16
      • 2017-06-19
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2019-06-20
      相关资源
      最近更新 更多