Spring Validation: @Valid, @NotNull 등 유효성 검사 완전 정복

Spring Boot로 REST API를 개발하다 보면 사용자의 입력값이 유효한지 검증하는 과정은 매우 중요합니다. 특히 프론트엔드나 외부 API 호출로부터 전달되는 데이터는 항상 신뢰할 수 없기 때문에, 서버단 유효성 검증은 선택이 아닌 필수입니다.

@Valid, @NotNull, @Size 등 다양한 유효성 검사 어노테이션을 중심으로, Spring의 Validation 기능을 실무에 어떻게 적용할 수 있는지 설명드립니다.

 

1. Spring Validation의 핵심 구성 요소

  • javax.validation (Jakarta Bean Validation API)
  • Hibernate Validator: Spring Boot에서 기본으로 사용하는 구현체
  • JSR-380 (Bean Validation 2.0) 스펙 기반 어노테이션

 

2. 의존성 추가 (Spring Boot 프로젝트)

spring-boot-starter-validation 의존성은 기본 포함되어 있으나, 확인이 필요하다면 아래 내용을 확인하세요:


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

 

3. DTO에 유효성 어노테이션 적용하기

입력값 검증은 대부분 DTO 클래스에서 이루어집니다.


import javax.validation.constraints.*;

public class UserRequest {

    @NotBlank(message = "이름은 필수입니다.")
    private String name;

    @Min(value = 18, message = "나이는 18세 이상이어야 합니다.")
    private int age;

    @Email(message = "이메일 형식이 올바르지 않습니다.")
    private String email;

    @Size(min = 8, max = 20, message = "비밀번호는 8~20자 사이여야 합니다.")
    private String password;

    // getter/setter 생략
}

4. Controller에서 @Valid 사용하기

컨트롤러에서는 @RequestBody@Valid를 함께 사용해 DTO의 유효성 검사를 수행합니다.


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

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserRequest request) {
        return ResponseEntity.ok("사용자 등록 성공");
    }
}

 

5. 검증 실패 시 에러 메시지 처리

검증이 실패하면 MethodArgumentNotValidException이 발생하며, 이를 @ControllerAdvice로 처리할 수 있습니다.


@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationErrors(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error -> {
            errors.put(error.getField(), error.getDefaultMessage());
        });
        return ResponseEntity.badRequest().body(errors);
    }
}

 

6. 주요 유효성 어노테이션 정리

어노테이션 설명
@NotNull null이 아니어야 함 (빈 문자열은 허용)
@NotEmpty null 또는 빈 문자열은 허용되지 않음
@NotBlank 공백만 있는 문자열도 허용하지 않음
@Email 이메일 형식인지 검사
@Size 문자열, 컬렉션 등의 길이 제한
@Min / @Max 숫자의 최소/최대값 제한
@Pattern 정규식 패턴 매칭

 

7. 실무 팁: Validation 어디까지 넣어야 하나?

  • DTO에서 모든 유효성 검사를 끝내는 것이 이상적입니다. 도메인 계층은 순수하게 유지하는 게 좋습니다.
  • Controller 단에서 검증 통과된 데이터만 Service로 전달하는 것이 유지보수에 유리합니다.
  • 복잡한 유효성은 @AssertTrue, @ScriptAssert 또는 커스텀 Validator를 만들어 분리할 수 있습니다.

 

8. 결론

Spring Validation은 @Valid, @NotNull 등 어노테이션 기반의 선언적 프로그래밍을 가능하게 해줍니다. 코드가 깔끔해지고, 보안과 안정성 측면에서도 큰 장점이 있습니다.

하지만 검증 로직이 너무 복잡해질 경우에는 도메인 객체로 책임을 넘기거나, 커스텀 Validator로 분리하는 설계도 고려해볼 필요가 있습니다.