У меня есть API для отдыха, написанный на Java (весенняя загрузка), мой запрос берет строку json из заголовка запроса (не спрашивайте, почему так :), например, {flowerId: 123} В моем контроллере я сопоставляю строку с объектом. Поэтому, когда пользователи передают ненужные данные, например, {flowerId: abc}, генерируется исключение JsonMappingException. Я хотел бы обработать исключение в моем обработчике исключений, но не смог перехватить его в своем обработчике. Я что-то пропустил? Спасибо
Смотрите мой код ниже.
@RestController
public class FlowerController {
@GetMapping
@ResponseStatus(HttpStatus.OK)
public GetFlowerResponse getFlowers(@RequestHeader(name = Constants.myHeader) String flowerIdString) throws IOException {
GetFlowerRequest getFlowerRequest = new ObjectMapper().readValue(flowerIdString, GetFlowerRequest.class);
//get Flower info with request ...
}
}
@RestControllerAdvice
public class ApplicationExceptionHandler {
@ExceptionHandler(value = {JsonMappingException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
public GetFlowerResponse processServletRequestBindingException(HttpServletRequest req, ServletRequestBindingException e) {
return buildExceptionResponse(e, ErrorMessages.INVALID_REQUEST.getCode(), e.getMessage());
}
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public GetFlowerResponse processUnhandledExceptions(HttpServletRequest req, Exception e) {
return buildExceptionResponse(e, ErrorMessages.SERVICE_UNAVAILABLE.getCode(), ErrorMessages.SERVICE_UNAVAILABLE.getDescription());
}
}
public class GetFlowerRequest {
int flowerId;
}
public class GetFlowerResponse {
private List<ReturnDetail> returnDetails;
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ReturnDetail {
@Builder.Default
private Integer code = 0;
@Builder.Default
private String message = "";
private String source;
Ваш обработчик исключений недействителен. Ваш метод processServletRequestBindingException()
объявляет исключение ServletRequestBindingException
качестве параметра, но аннотируется для @ExceptionHandler(value = {JsonMappingException.class})
. Эти типы исключений должны быть совместимы, иначе это не будет работать, и вы получите исключение во время обработки исключений.
new ObjectMapper().readValue()
выбрасывает как JsonParseException
и JsonMappingException
. Оба расширяют JsonProcessingException
поэтому вам, скорее всего, понадобится обработчик для этого исключения, чтобы охватить оба случая:
@ExceptionHandler(JsonProcessingException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public GetFlowerResponse handleJsonProcessingException(
HttpServletRequest req, JsonProcessingException ex) {
...
}
Обратите внимание, что предпочтительнее autowire ObjectMapper
из контекста Spring и не создавать новый экземпляр.
Handler
и создает bean-компонентJsonParseException
исключениеJsonParseException
. Если формат JSON правильный, но входные данные недопустимы (пример: строка передается там, где ожидается целое число), то обычно вызываетсяJsonMappingException
. Вероятно, вы должны также пойматьJsonParseException
.