Почему 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 шт):
Наконец-то я решил эту проблему.
Изначально класс 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 валидатора, данный метод брал всё на себя. Но интересно то, что данный метод обрабатывал не все исключения. Эту проблему я решил так:
- Убрал
extends ResponseEntityExceptionHandler - Создал свой метод обработки всех
BindException:
@ExceptionHandler(BindException.class)
private ResponseEntity<?> handleConstraintViolationException(BindException e, Locale locale) {
EsmHttpErrorCode esmHttpErrorCode = EsmHttpErrorCode.ENTITY_VALIDATION;
return createResponseEntity(e, HttpStatus.BAD_REQUEST, esmHttpErrorCode, locale);
}