@Valid Vs. @Validated

na.ram·2024년 8월 13일

Spring

목록 보기
2/13
post-thumbnail

@Valid

JSR-303 표준 스펙(자바 진영 스펙)으로써 빈 검증기(Bean Validator)를 이용해 객체의 제약 조건을 검증하도록 지시하는 어노테이션이다.

@Valid 사용

DTO에 검증이 필요한 필드에 @NotNull 어노테이션과 같은 어노테이션들을 달아주고, Controller의 메서드의 (유효성 검증이 필요한) 파라미터에 @Valid 어노테이션을 붙이면 유효성 검증이 진행된다.

@Valid 동작 원리

모든 요청은 Front Controller인 Dispatcher Servlet을 통해 Controller로 전달된다. 전달 과정에서는 Controller 메서드의 객체를 만들어주는 ArgumentResolver가 동작하는데, @Valid 역시도 이 ArgumentResolver에 의해 처리된다.

대표적으로 @RequestBody는 Json 메세지를 객체로 변환해주는 작업이 ArgumentResolver의 구현체인 RequestResponseBodyMethodProcessor가 처리하며 이 내부에서 @Valid로 시작하는 어노테이션이 있을 경우에는 유효성 검사를 진행한다.

만약 @ModelAttribute를 사용중이라면 ModelAttributeMethodProcessor에 의해 처리된다.

만약 검증에 오류가 있다면 MethodArgumentNotValidException 예외가 발생하고, Dispatcher Servlet에 기본으로 등록된 ExceptionResolver인 DefaultHandlerExceptionResolver에 의해 400 BadRequest 에러가 발생한다.

이런 이유들로 인해 @Valid는 기본적으로 Controller에서만 동작하며 다른 계층에서는 검증을 수행하지 못한다. 만약 다른 계층에서 파라미터를 검증하기 위해서는 @Validated와 결합되어야 한다.

@Validated

입력 파라미터에 대한 유효성 검증은 최대한 Controller에서 처리하고 넘기는 것이 좋지만 불가피하게 다른 계층에서 검증을 수행해야 할 수도 있다. 이를 위해 Spring에서 AOP 기반으로 메서드의 요청을 가로채 유효성 검증을 진행하는 @Validated를 제공한다.

@Validated 사용

클래스에 @Validated 어노테이션을 선언해주고, 메서드의 (유효성 검증이 필요한) 파라미터에 @Valid 어노테이션을 붙이면 유효성 검증이 진행된다.

@Validated 동작 원리

AOP 기반으로 메서드의 요청을 인터셉트하여 처리된다. @Validated를 클래스 레벨에 선언하면 해당 클래스의 유효성 검증을 위한 AOP의 어드바이스 또는 인터셉터(MethodValidationInterceptor)가 등록된다. 이는 해당 클래스의 메서드들이 호출될 때 요청을 가로채서 유효성 검증을 진행한다.

만약 검증에 오류가 있다면 ConstraintViolationException 예외가 발생한다.

이런 이유들로 인해 @Validated를 사용하면 Controller, Service, Repository 등 계층과 무관하게 Spring Bean이라면 유효성 검증을 진행할 수 있다.

0개의 댓글