我想根据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可以解决此问题,但不幸的是它没有解决。 我了解错误的原因,但是处理此类要求的方法是什么?
答案 0 :(得分:3)
您的问题是http://localhost:8080/users/12223
与/users/{id:\\d+}
和/users/{email}
都匹配。 12223是这两种方法的有效参数:
{id:\\d+}
匹配,因为它具有全数字{email}
,因为未指定正则表达式,并且任何参数都将匹配电子邮件。Spring无法选择合适的端点并给出错误:为HTTP路径映射的模糊处理程序方法。
如果您尝试其他参数,例如:http://localhost:8080/users/somebody@example.com
,则不会出现错误。 Spring将能够发现somebody@example.com与id
不匹配,而与email
相匹配。
正如JB Nizet在评论中提到的那样,您有2种解决方法:
{email:.+@.+\..+}
弄清推荐的pDer666之类的端点:
@GetMapping(value =“ / email / {email}”)
@GetMapping(value =“ / id / {id:\ d +}”)
答案 1 :(得分:1)
有多种解决方法。可以提供两个具有不同路径的GetMapping,或者仅在一个get请求中使用查询参数。如果设置了电子邮件,则通过电子邮件检索数据。如果设置了电子邮件,则通过其他参数检索数据。使用此解决方案,您可以轻松添加更多要搜索的参数,并且可以通过OR或AND查询数据,而无需添加新的控制器方法。
网址:http://localhost:8080/users?email=asdf@somewhere.com或http://localhost:8080/users?id=1234
@GetMapping
@ResponseBody
public String findOne(@RequestParam("id") long id, @RequestParam("email") String email) {
...
}