Spring RestController-findById和findByEmail请求方法不起作用(歧义处理程序)

时间:2018-07-04 19:54:15

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

我想根据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: Ambiguous handler methods mapped for HTTP path 'http://localhost:8080/users/12223': {public com.ofloy.persistence.model.User com.ofloy.rest.controller.UserController.findOneById(java.lang.Integer), public com.ofloy.persistence.model.User com.ofloy.rest.controller.UserController.findOneByEmail(java.lang.String)}

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

2 个答案:

答案 0 :(得分:3)

您的问题是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将能够发现somebody@example.com与id不匹配,而与email相匹配。

正如JB Nizet在评论中提到的那样,您有2种解决方法:

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

    @GetMapping(value =“ / email / {email}”)

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

答案 1 :(得分:1)

有多种解决方法。可以提供两个具有不同路径的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) {
    ...
}