[Spring] @Valid @Validated

Yoon Uk·2023년 5월 28일
0

Spring

목록 보기
5/5
post-thumbnail
post-custom-banner

Spring Framework에서 데이터 유효성 검사는 사용자 입력의 무결성과 신뢰성을 보장하는 데 중요한 역할을 합니다.
유효성 검사 프로세스를 단순화하기 위해 Spring은 @Valid 및 @Validated라는 두 가지 어노테이션을 제공합니다. 이를 통해 Spring 애플리케이션의 데이터 유효성을 검사하고 특정 요구 사항 및 제약 조건을 충족하는지 확인하는 데 도움이 됩니다. 이 블로그 게시물에서는 @Valid와 @Validated의 차이점과 각 어노테이션을 사용하는 경우를 살펴보겠습니다.

0. Gradle

@Valid와 @Validated를 사용하기 위해서는 다음과 같은 의존성을 추가해야 합니다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-validation'
}

1. @Valid

@Valid는 JSR-303 표준 스펙으로, 빈 검증기를 이용해 객체의 제약 조건을 검증하도록 지시하는 어노테이션입니다.
예를 들어, @NotNull은 필드의 값이 null이 아님을 확인하고, @Email은 필드의 값이 이메일 형식임을 확인합니다.
@Valid는 컨트롤러의 메소드 파라미터에 적용할 수 있으며, 유효성 검사에 실패하면 MethodArgumentNotValidException 예외가 발생합니다.

  • @ValidController에서 직접적으로 유효성 검증을 처리합니다.
  • 메소드 파라미터@Valid 어노테이션을 붙여 검증을 수행합니다. 검증 결과는 BindingResult 객체에 담겨 반환됩니다.

2. @Validated

@Validated는 Spring에서 제공하는 어노테이션으로, @Valid의 기능을 포함하고 추가적으로 그룹화된 유효성 검증을 지원합니다. 그룹화된 유효성 검증이란, 객체의 필드에 그룹을 지정하고, 컨트롤러의 메소드에서 해당 그룹만 유효성 검사를 수행하도록 하는 기능입니다.
예를 들어, 회원가입과 로그인에서 사용하는 UserDto 클래스가 있다면, 회원가입 시에는 모든 필드를 검증해야 하지만, 로그인 시에는 아이디와 비밀번호만 검증하면 됩니다. 이런 경우에 그룹화된 유효성 검증을 사용할 수 있습니다.

  • @Validated는 @Valid와 유사하지만, 빈으로 등록되어 있는 클래스에 붙어 검증을 수행합니다.
    여러 검증 그룹을 사용할 수 있으며, 검증 결과는 BindingResult 대신 Errors 객체에 담겨 반환됩니다.

3. @Valid와 @Validated의 차이

  • @Valid는 컨트롤러에서 직접적으로 유효성 검증을 처리하고, @Validated는 빈으로 등록된 클래스에서 유효성 검증을 처리합니다.

  • @Valid는 검증 결과를 BindingResult에 담고, @Validated는 Errors에 담습니다.

  • @Valid는 검증 그룹을 사용할 수 없지만, @Validated는 검증 그룹을 사용할 수 있습니다.

4. 예시

@Valid와 @Validated의 사용 방법은 다음과 같습니다.

1) @Valid

@Valid는 메소드 파라미터에 붙여 사용합니다.

@Getter
@Setter
public class ArticleRequestDto {

    private Long articleId;

    @Max(15)
    @Min(1)
    private String title;

    @Max(1000)
    @Min(1)
    private String contents;

    private String author;
@PostMapping("/articles")
public ResponseEntity<?> createArticle(@Valid @RequestBody ArticleDto articleDto) {
    // ...
}

2) @Validated

@Validated는 빈으로 등록된 클래스에 붙여 사용합니다.

@Service
@Validated
public class UserService {
 
    public void createUser(@Valid UserDto userDto) {
        // ...
    }
}

다른 방법으로는
검증 그룹을 지정하기 위해 마커 인터페이스(내용 없이 중괄호({})만 있는)를 간단히 정의한다.

public interface AnonymousValidationGroup {} 
public interface AuthorValidationGroup {}

그리고 해당 제약 조건이 적용될 그룹을 groups로 지정해준다.
제약 조건이 적용될 그룹이 여러 개라면 {}를 이용해 그룹의 이름을 모두 넣어주면 된다.
예를 들어 다음과 같이 DTO에 그룹 속성을 지정해줄 수 있다.

@NotEmpty(groups = {AnonymousValidationGroup.class, AuthorValidationGroup.class} ) 
private String author; 

@NotEmpty(groups = AnonymousValidationGroup.class) 
private String anonymousId; 

@NotEmpty(groups = AuthorValidationGroup.class) 
private String authorId;

Controller에서는 아래와 같이 사용한다.

@PostMapping("/articles") 
public ResponseEntity<Void> createArticle(
    @RequestBody @Validated(AnonymousValidationGroup.class) ArticleRequestDto articleRequestDto) {
    
      ...
}

만약 위와 같이 AnonymousValidationGroup을 @Validated의 파라미터로 넣어주었다면 AnonymousValidationGroup에 해당하는 제약 조건만 검증이 된다.

@Validated에 특정 마커를 지정해주지 않았거나, groups가 지정되어 있는데 @Valid를 이용하면 다음과 같이 처리된다.

  • @Validated에 특정 클래스를 지정하지 않는 경우: groups가 없는 속성들만 처리
  • @Valid or @Validated에 특정 클래스를 지정한 경우: 지정된 클래스를 groups로 가진 제약사항만 처리

5. 참고

https://mangkyu.tistory.com/174

post-custom-banner

0개의 댓글