Почему Exception Handler не обрабатывает ошибку валидации в GET запросе?

В контроллере есть два метода с валидацией аргумента, один метод GET, другой - POST. Почему в случае с POST методом Exception Handler отлавливает исключение при передаче невалидных данных в виде JSON и выводит ответ в виде JSON в Tomcat, а при GET методе при вводе невалидных данных Exception Handler даже не обрабатывает исключение и не выдает ответ в виде JSON, а только выводит статус операции как 400 Bad Request?

@PostMapping
public EntityModel<TagDto> create(@Valid @RequestBody TagDto tagDto) {
    // тут срабатывает исключение при вводе невалидных данных и обрабатывается
}

@GetMapping
public CollectionModel<TagDto> findAll(@Valid EsmPagination pagination) {
    //  При вызове данного метода Exception Handler не обрабатывает исключение при невалидных данных
}

Хоть объекты TagDto и EsmPagination имеют внутри эквивалентную структуру:

TagDto

@AllArgsConstructor
@RequiredArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
public class TagDto extends RepresentationModel<TagDto> {
    private Long id;

    @NotBlank(message = MessagePropertyKey.VALIDATION_TAG_NAME_NOT_EMPTY)
    @Pattern(regexp = DtoRegexValidator.TAG_NAME,
            flags = Pattern.Flag.UNICODE_CASE,
            message = MessagePropertyKey.VALIDATION_TAG_NAME)
    private String name;
}

EsmPagination:

@AllArgsConstructor
@Getter
@Setter
@ToString
public class EsmPagination implements Serializable {
    private static final int MIN_PAGE_INDEX = 1;
    private static final int DEFAULT_ELEMENTS_ON_PAGE = 10;

    @Min(value = MIN_PAGE_INDEX, message = MessagePropertyKey.EXCEPTION_ESM_PAGINATION_PAGE_INCORRECT_VALUE)
    private int page;

    @Positive(message = MessagePropertyKey.EXCEPTION_ESM_PAGINATION_SIZE_INCORRECT_VALUE)
    private int size;

    public EsmPagination() {
        this.page = MIN_PAGE_INDEX;
        this.size = DEFAULT_ELEMENTS_ON_PAGE;
    }
}

Также пробовал добавлять аннотацию @RequestBody, на всякий случай, но не работает тоже:

@GetMapping
public CollectionModel<TagDto> findAll(@Valid @RequestBody EsmPagination pagination) {
    //  При вызове данного метода Exception Handler не обрабатывает исключение при невалидных данных
}

Ответы (1 шт):

Автор решения: Taylor

Наконец-то я решил эту проблему.

Изначально класс ExceptionHandler у меня наследовался от ResponseEntityExceptionHandler и объявление его выглядело следующим образом:

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
...
}

А обработкой ошибок занимался переопределенный мной метод:

@Override
    protected @NotNull ResponseEntity<Object> handleMethodArgumentNotValid(
            @NotNull MethodArgumentNotValidException e, @NotNull HttpHeaders headers, @NotNull HttpStatus httpStatus, WebRequest request) {
        Locale locale = request.getLocale();
        EsmHttpErrorCode esmHttpErrorCode = EsmHttpErrorCode.ENTITY_VALIDATION;
        return createResponseEntity(e, httpStatus, esmHttpErrorCode, locale);
    }

Соответственно, при возникновении любой ошибки при валидации с помощью Hibernate валидатора, данный метод брал всё на себя. Но интересно то, что данный метод обрабатывал не все исключения. Эту проблему я решил так:

  1. Убрал extends ResponseEntityExceptionHandler
  2. Создал свой метод обработки всех BindException:
@ExceptionHandler(BindException.class)
    private ResponseEntity<?> handleConstraintViolationException(BindException e, Locale locale) {
        EsmHttpErrorCode esmHttpErrorCode = EsmHttpErrorCode.ENTITY_VALIDATION;
        return createResponseEntity(e, HttpStatus.BAD_REQUEST, esmHttpErrorCode, locale);
    }
→ Ссылка