Back-end/Spring

[Spring] Spring만의 유효성 검사 @Valid, @Validated 정리

류건 2024. 6. 27. 17:49
반응형

실행 환경

build.gradle

implementation 'org.springframework.boot:spring-boot-starter-validation:3.2.2'

 

 

1. @Valid

Valid 어노테이션은 주로 request body를 검증하는데 많이 사용된다.

다음 UserDto를 보자

public class UserDto {
    @Email
    private String email;

    @NotBlank
    private String password;
    
    @Valid // @NotNull 대신 @Valid를 사용해야함
    private Address address;

   // 생성자 및 getter 함수
}

public class Address {
    @NotBlank
    private String city;

    @NotBlank
    private String zipCode;
    
    // 생성자 및 getter 함수
}

 

 

Controller 내의 User 회원가입 함수(signUp) 파라미터 부분에 Valid 어노테이션을 적어야 기능이 정상 작동한다.

@PostMapping()
public String signUp(@Valid @RequestBody UserRequest request) {
    return "ok";
}

 

 

nested DTO를 검증하기 위해선 무조건 @Valid를 사용해야 한다!

2. @Validated

@Validated 어노테이션은 쿼리 스트링 또는 쿼리 파라미터를 검증하는데 사용된다.

1. query string.    ex) /users?teamId=1
2. query parameter. ex) /users/1

 

적용

첫 번째로, 쿼리 파라미터로 특정 사용자를 조회하는 API가 있다고 가정하자.

 

id는 보통 db의 auto_increment로 1부터 시작하니 이걸 검증한다고 하면 아래와 같이 Validated 어노테이션을 클래스 레벨에 선언 후 유효성 검사하는 어노테이션을 추가하면 된다.

@RestController
@RequestMapping("/users")
@Validated
public class UserController {
    
    @GetMapping("/{id}")
    public String find(@PathVariable @Min(1)  Long id) {
        return "ok";
    }
}

 

 

만약 class 레벨에 Validated 어노테이션이 없다면 Min 어노테이션은 동작하지 않는다. 

 

두 번째로, controller가 아닌 service에서 검증한다고 가정해보자.

Service class 단에 Validated 어노테이션을 선언하고 파라미터에 Valid 어노테이션을 적용하면 된다.

@Transactional(readOnly = true)
@Validated   // Validated 어노테이션 추가
@Service
public class UserService {

  @Transactional
  public void signUp(@Valid UserRequest request) { // 파라미터에 Valid 추가
    // 회원가입 로직
  }
}

 

 

3. 예외 처리

만약 Valid 방법을 선택했는데 입력 값 검증 과정에서 예외가 발생한다면 이는 MethodArgumentNotValidException예외를 발생시키고 Exception Handler로 핸들링 할 수 있다.

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseMessage<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    return ResponseMessage.badRequest("");
}
jakarta.validation 어노테이션으로 import 해야 함!

 

# 정리

1. @Valid는 자바 표준 스펙이고 @Validated는 스프링에서 제공하는 어노테이션이다.
2. @Validated를 통해 그룹 유효성 검사나 Controller가 아닌 다른 계층에서 유효성 검증 가능
3. @Valid는 MethodArgumentNotValidException 예외를, @Validated는 ConstraintViolationException 예외를 발생시킨다.

반응형