[Spring] @Valid와 @Validated

Jihyoung·2023년 6월 27일
2

Spring

목록 보기
5/5
post-thumbnail

스프링에서 유효성 검증을 위한 어노테이션으로 @Valid@Validated 를 사용하는데 그 둘의 차이점에 대해 정확하게 파악한 후 사용해야겠다는 생각이 들어 해당 글을 작성하게 되었습니다.


@Valid

@Valid 는 Bean Validator를 통해 객체의 데이터 유효성 검증을 지시하는 어노테이션입니다. 하지만 이는 Bean Validation의 표준 명세일 뿐 구현체를 가지고 있지는 않습니다. 그래서 구현체를 따로 연결해서 사용해야 합니다.

그래서 Spring에서는 이 구현체를 Hibernate Validator를 사용합니다. Hibernate Validator는 Bean Validator의 모든 어노테이션을 구현하고 있습니다.

따라서 dependency에 아래와 같은 코드를 추가하여 사용합니다.

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.1.Final</version>
</dependency>

@Valid의 동작 과정

Client에서 요청이 들어오면 Dispatcher Servlet에서 요청에 맞는 컨트롤러에 요청을 전달합니다.

이때, 전달 과정에서 컨트롤러 메소드의 객체를 전달해주는 HandlerMethodArgumentResolver 동작하는데, @Valid 역시 HandlerMethodArgumentResolver 의해 처리가 됩니다.

* ArgumentResolver : @RequestBody가 붙은 데이터를 Json 포멧으로 변경

HandlerMethodArgumentResolver의 resolveArgument 메소드에서 @Valid로 시작하는 어노테이션이 붙어있으면 dispathcher servlet 단에서 검사 valid를 진행하는 식으로 동작하며, 아래와 같이 검증을 할 파라미터에 @Valid를 붙여줘야 유효성 검증이 진행됩니다.

따라서 Valid 어노테이션은 주로 Controller에서 request body를 검증 하는데 많이 사용됩니다.

@PostMapping("/") 
public String doSomething(@Valid Request request) {
      ...
}

그리고 오류가 발생하면 MethodArgumentNotValidException이 발생하고, 디스패치 서블릿에 기본으로 등록된 Exception Resolver인 DefaultHandlerExceptionResolver에 의해 400 에러가 발생하게 됩니다.

Spring에서 @Valid는 기본적으로 Controller에서만 동작하도록 설계되어있고 다른 계층에서는 검증이 되지 않기 때문에 다른 계층에서 검증하기 위해서는 @Validated와 결합하여 사용합니다.


@Validated

@Validated는 Controller 뿐만 아니라 다른 계층에서도 데이터 유효성 검증을 해야하는 경우 메소드 요청을 가로채서 유효성 검증을 해주는 Spring AOP 기반 기능입니다.

사용법은 아래와 같이 유효성 검증이 필요한 클래스에 @Validated를 붙이고, 유효성 검증을 할 파라미터에 @Valid를 붙이면 동작하게 됩니다.

@Service
@Validated
public class Service {

    public void doSomething(@Valid Request request) {
        ...
    }
}

오류가 발생하면 @Valid와 다르게 ConstraintViolationException이 발생합니다.

@Validated 동작 과정

@Validated를 클래스에 선언하면 해당 클래스에 유효성 검증을 위한 인터셉터인 MethodValidationInterceptor가 등록됩니다.
그리고 해당 클래스의 메소드가 호출 될 때 AOP가 포인트컷으로 확인을 하고 요청을 중간에 가로채어 유효성 검증을 진행하게 됩니다.

@Validated는 Spring의 기능이기 때문에 Spring Bean이라면 모두 유효성 검증이 가능하다는 특징을 가집니다. 그리고 MethodValidationInterceptor에 Validator이 의존성 주입으로 들어가므로 @Valid와 똑같이 Hibernate Validator를 사용하기 때문에 Bean Validation을 그대로 이용할 수 있게 됩니다.


정리

@Valid@Validated
자바 표준 스펙

javax.validation 패키지에 속함
스프링에서 제공하는 어노테이션

org.springframework.validation.annotation에 속함
request body 검증 시 사용그룹 유효성 검사나 Controller가 아닌 다른 계층에서 유효성 검증 시 사용
MethodArgumentNotValidException 예외 발생ConstraintViolationException 예외 발생

Reference

관련 공식 문서

관련 블로그

profile
로그를 생활화

1개의 댓글

comment-user-thumbnail
2023년 7월 3일

오 저도 @Valid 와 @Validated의 차이에 대해 이번에 알게되었네요 ❕
마지막에 두 개의 차이를 보기쉽게 정리해주셔서 더 기억에 잘 남을 것 같아요
포스팅 잘 읽었습니다 👍

답글 달기