Краткий ответ. Вы не можете смешивать разные типы в одном @PathVariable, как говорит Spring в своей документации.
Согласно документации Spring IO о @PathVariable
:
Аргумент @PathVariable может иметь любой простой тип, например int, long, Date и т. Д. Spring автоматически преобразуется в соответствующий тип или выдает исключение TypeMismatchException, если это не удается сделать.
Обратите внимание на то, что документация обрисовывает в общих чертах Аргумент @PathVariable как тип единственного объекта, который не взаимозаменяем с различными типами.
Кроме того, совершенно нормально иметь обработку исключений, как было дано в ответе на другой вопрос о стекопереработке , что попытка определить Long из String без try/catch
даже не стоит работы и снижает производительность.
Вы можете использовать один @PathVariable
и иметь блок try/catch
для захвата NumberFormatException
или просто регулярное выражение.
Метод 1: Обработка исключений
@RequestMapping(value="/user/{identifier}", method=RequestMethod.GET)
public User findUser(@PathVariable("identifier") String identifier) {
try {
Long long_identifier = Long.parseLong(identifier);
this.userRepository.findByIdOrName(long_identifier);
} catch(NumberFormatException nfe) {
//We know it's a plain string by now.
this.userRepository.findByIdOrName(identifier);
}
}
Метод 2: регулярное выражение
Примечание: если значение не найдено, запрос должен просто вернуть пустой результат.
@RequestMapping(value="/user/{identifier}", method=RequestMethod.GET)
public User findUser(@PathVariable("identifier") String identifier) {
//Check for digits only
String regexpr = "\\d+";
this.userRepository.findByIdOrName(
identifier.matches(regexpr)
? Long.parseLong(identifier)
: identifier
);
}
Метод 3: запрос сопоставлений с регулярным выражением
@RequestMapping(value="/user/{identifier:[A-Za-z]+}", method=RequestMethod.GET)
public User findUserByString(@PathVariable("identifier") String identifier) {
this.userRepository.findByIdOrName(identifier);
}
@RequestMapping(value="/user/{identifier:[0-9]+}", method=RequestMethod.GET)
public User findUserByLong(@PathVariable("identifier") Long identifier) {
this.userRepository.findByIdOrName(identifier);
}