티스토리 뷰

Spring

[Spring] @Valid vs. @Validated

snail voyager 2025. 4. 29. 00:01
728x90
반응형

@Valid

  • Java의 표준 Bean Validation API(javax.validation.Valid)에서 제공
  • 단일 객체(단순 DTO)에 대한 유효성 검사 수행
  • 중첩 객체(내부 객체)도 함께 검사
  • 그룹(group) 검증 기능 없음
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

public class UserDto {
    @NotNull
    private String name;

    @Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.")
    private String password;

    // Getter, Setter 생략
}

Controller에서 @Valid 사용

import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/users")
public class UserController {
    
    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDto userDto) {
        return ResponseEntity.ok("유효성 검사 통과!");
    }
}

@Valid의 특징

  • UserDto의 필드를 검증함
  • @Valid를 사용하면, UserDto 내부에 있는 다른 객체도 재귀적으로 검증 가능
  • 그룹(group) 검증 기능이 없음
  • Spring이 아닌 Java 표준이므로 Hibernate Validator를 포함한 여러 프레임워크에서 사용 가능

@Validated

  • Spring 프레임워크에서 제공하는 어노테이션 (org.springframework.validation.annotation.Validated)
  • 단일 객체뿐만 아니라 개별 필드에도 사용 가능
  • 그룹(group) 검증을 지원 → 특정 유효성 검사 그룹을 지정할 수 있음
  • @Valid와 달리 인터페이스에도 적용 가능
import org.springframework.validation.annotation.Validated;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

@Validated
public class UserDto {
    @NotNull
    private String name;

    @Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.")
    private String password;
}

Controller에서 @Validated 사용

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/users")
@Validated // 클래스 단위로 유효성 검사 적용 가능
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@Validated @RequestBody UserDto userDto) {
        return ResponseEntity.ok("유효성 검사 통과!");
    }

    // 개별 파라미터 검증 가능
    @GetMapping("/{id}")
    public ResponseEntity<String> getUser(@PathVariable @NotNull Long id) {
        return ResponseEntity.ok("User ID: " + id);
    }
}

@Validated의 특징

  • 클래스나 메서드 단위로 선언 가능 (@Validated를 클래스에 선언하면 모든 메서드에 적용)
  • 개별 파라미터(@PathVariable, @RequestParam)에도 적용 가능
  • 그룹(Group) 검증을 지원
  • @Valid보다 유연성이 높고 다양한 검증 기능을 제공

그룹 검증 예제 (@Validated만 가능)

  • 특정 유효성 검사를 적용할 그룹을 지정할 수 있음
  • 예제: CreateGroup, UpdateGroup 두 개의 그룹을 만들어 사용
  • createUser()는 CreateGroup 기준으로 검증
  • updateUser()는 UpdateGroup 기준으로 검증
public interface CreateGroup {}
public interface UpdateGroup {}


import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import org.springframework.validation.annotation.Validated;

@Validated
public class UserDto {
    
    @NotNull(groups = CreateGroup.class)
    private String name;

    @Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.", groups = {CreateGroup.class, UpdateGroup.class})
    private String password;
}


import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;

@RestController
@RequestMapping("/users")
@Validated
public class UserController {

    @PostMapping("/create")
    public ResponseEntity<String> createUser(@Validated(CreateGroup.class) @RequestBody UserDto userDto) {
        return ResponseEntity.ok("Create 유효성 검사 통과!");
    }

    @PutMapping("/update")
    public ResponseEntity<String> updateUser(@Validated(UpdateGroup.class) @RequestBody UserDto userDto) {
        return ResponseEntity.ok("Update 유효성 검사 통과!");
    }
}

@Validated를 클래스에 선언하면?

 

  • @RequestBody DTO의 유효성 검사가 자동으로 수행되지 않습니다.
  • @Validated는 기본적으로 메서드 파라미터(@PathVariable, @RequestParam 등)에 대한 유효성 검사만 활성화합니다.
  • 따라서 @RequestBody에 대한 DTO 검증은 적용되지 않음.

 

@RestController
@RequestMapping("/users")
@Validated // 컨트롤러 전체에 유효성 검사 적용
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@RequestBody UserDto userDto) {
        return ResponseEntity.ok("유효성 검사 통과!");
    }
}

@Validated를 @RequestBody 앞에도 선언

@PostMapping
public ResponseEntity<String> createUser(@Validated @RequestBody UserDto userDto) {
    return ResponseEntity.ok("유효성 검사 통과!");
}

 

728x90
반응형
반응형
300x250