Пустые результаты @PathVariable в ArgumentMismatchException
У меня есть конечная точка в моем контроллере, настроенная так:
@RequestMapping(value = "/users/{userId}/data", method = RequestMethod.GET)
public void getUserData(@PathVariable("userId") @Valid @NotNull Integer userId, HttpServletRequest request) {
}
Если клиент отправляет запрос на эту конечную точку с пустым userId
Я предполагаю, что Spring интерпретирует URL как /users//data
потому что это исключение выдается:
2017-03-03 11: 13: 41,259 [[ACTIVE] ExecuteThread: '3' для очереди: 'weblogic.kernel.Default (самостоятельная настройка)'] Класс ERROR com.xxxx.web.controller.custom.ExceptionHandlingController: RuntimeException thrown: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: не удалось преобразовать значение типа 'java.lang.String' в требуемый тип 'java.lang.Integer'; вложенным исключением является java.lang.NumberFormatException: для входной строки: "данные"
Каков наилучший способ справиться с этим вариантом использования? Я осторожен с кастингом userId
как String и ловить исключение, которое выглядит как взломать. Я не хочу полагаться на то, что клиент всегда отправляет правильный запрос. В настоящее время я использую Spring-Boot v1.2.6.RELEASE и хочу обновить версии, если я знаю, что это исправит.
2 ответа
У вас есть конфликт в отображении вашего запроса.
Скорее всего, у вас также есть GET картирование для /users/{userId}
, Это отображение, которое было применено вместо того, что из вашего вопроса.
Проблема в том, что вы запрашиваете /users//data
Веб-сервер автоматически заменяет двойную косую черту на одну. Результат запроса в точности соответствует этому шаблону /users/{userId}
но не тому, который вы опубликовали. Наконец весна не может быть брошена data
как целое число
Если вы удалите /users/{userId}
(только для проверки) вы, вероятно, получите код ошибки 404, запрашивающий тот же URL.
РЕДАКТИРОВАТЬ:
На самом деле вас не должно волновать, что кто-то отправляет неправильные запросы в ваш REST API. REST API - это контракт, и обе стороны должны следовать этому контракту. Вы, как бэкэнд, должны обрабатывать только запрос и предоставлять соответствующий код ошибки и хорошее описание на случай, если запрос неверный. data
никогда не был правильный идентификатор пользователя, убедитесь, что эта информация включена в ответ, а не технические вещи.
Одним из возможных решений является проверка идентификаторов с использованием шаблона. В вашем случае это будет выглядеть так:
@RequestMapping(value = "/users/{userId:\\d+}/data", method = GET)
@RequestMapping(value = "/users/{userId:\\d+}", method = GET)
В этом случае Spring автоматически отфильтрует нечисловые идентификаторы и предоставит для них HTTP 404.
Вы можете создать класс для обработки глобальных исключений и аннотировать его с помощью @ControllerAdvice.
@ControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandle {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<Object> handleMethodArgumentTypeMismatch(
MethodArgumentTypeMismatchException ex, WebRequest request) {
//Handle your exception here...
}
}
Вот хорошее описание того, что можно сделать с помощью @ControllerAdivce.
http://www.baeldung.com/global-error-handler-in-a-spring-rest-api