Spring RestController - метод запроса findById и findByEmail не работает (неоднозначный обработчик) - PullRequest
0 голосов
/ 04 июля 2018

Я хочу получить информацию 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 голосов
/ 04 июля 2018

Ваша проблема в том, что 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.

Как отметил в комментариях Дж. Б. Низет, у вас есть 2 способа решить эту проблему:

  1. Укажите регулярное выражение для электронной почты в соответствии с форматом электронной почты, например, {email:.+@.+\..+}
  2. Уточните конечные точки, например, рекомендуется pDer666:

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

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

0 голосов
/ 04 июля 2018

Существуют разные способы решения этой проблемы. Можно предоставить два GetMappings с разными путями или использовать параметры запроса только в одном запросе get. Если адрес электронной почты установлен, вы извлекаете данные по электронной почте. Если другой набор установлен, извлекайте его по другому параметру. С помощью этого решения вы можете легко добавить дополнительные параметры для поиска, и у вас есть возможность запрашивать данные с помощью ИЛИ или И, не добавляя новый метод контроллера.

URL: 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) {
    ...
}
...