Невозможно отловить JsonMappingException в обработчике исключений

У меня есть 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;

1 ответ

Ваш обработчик исключений недействителен. Ваш метод 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 и не создавайте новый экземпляр.

Другие вопросы по тегам