본문 바로가기

Spring Boot

Spring Boot에서 데이터 유효성(Validation) 검사를 적용하는 방법

반응형

Spring Boot에서 간단한 데이터 유효성 검사를 적용하는 방법

Spring Boot에서 데이터 유효성 검사는 클라이언트로부터 받은 데이터가 애플리케이션에서 요구하는 조건에 부합하는지 확인하는 중요한 단계입니다. Spring Boot는 Java Bean Validation API(JSR 380)와 Hibernate Validator를 사용하여 간단하고 강력한 데이터 검증 기능을 제공합니다.


1. 데이터 유효성 검사란?

데이터 유효성 검사는 클라이언트로부터 받은 입력 값이 유효한지 확인하는 작업입니다. 예를 들어, 사용자가 제출한 이메일 주소 형식이 올바른지, 비밀번호 길이가 적절한지 등을 검증할 수 있습니다.


2. 프로젝트 설정

Spring Boot는 기본적으로 Hibernate Validator를 포함하고 있으므로 별도의 의존성을 추가하지 않아도 됩니다. 그러나 프로젝트에 필요한 경우 spring-boot-starter-validation 의존성을 명시적으로 추가할 수 있습니다.

Maven:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Gradle:

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

3. 유효성 검사 적용하기

  1. DTO 클래스에 어노테이션 추가

유효성 검사는 데이터 전송 객체(DTO)에 어노테이션을 추가하여 적용할 수 있습니다. 다음은 사용자 데이터에 유효성 검사를 적용한 예제입니다:

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public class UserDTO {

    @NotBlank(message = "이름은 필수 항목입니다.")
    @Size(min = 2, max = 30, message = "이름은 2자 이상 30자 이하로 입력해야 합니다.")
    private String name;

    @NotBlank(message = "이메일은 필수 항목입니다.")
    @Email(message = "유효한 이메일 주소를 입력해야 합니다.")
    private String email;

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

    // Getter와 Setter
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
  1. 컨트롤러에서 유효성 검사 적용

컨트롤러에서 @Valid 어노테이션을 사용하여 DTO 객체의 유효성을 검사합니다. 검사 결과는 BindingResult를 통해 확인할 수 있습니다.

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

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

    @PostMapping
    public String createUser(@Valid @RequestBody UserDTO userDTO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return bindingResult.getAllErrors().get(0).getDefaultMessage();
        }
        return "사용자가 성공적으로 생성되었습니다: " + userDTO.getName();
    }
}

4. 주요 유효성 검사 어노테이션

어노테이션 설명
@NotBlank 값이 null이 아니고, 공백이 아닌 문자가 있어야 합니다.
@NotNull 값이 null이 아니어야 합니다.
@Size 문자열, 컬렉션 등의 길이나 크기를 제한합니다.
@Email 유효한 이메일 형식인지 확인합니다.
@Pattern 정규식을 사용하여 값이 특정 패턴과 일치하는지 확인합니다.
@Min / @Max 숫자의 최소값과 최대값을 설정합니다.

5. 유효성 검사 실패 시 반환 처리

Spring Boot에서는 기본적으로 유효성 검사 실패 시 예외를 발생시킵니다. 이를 사용자 정의 응답으로 처리하려면 @ControllerAdvice를 사용할 수 있습니다.

예제:

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class ValidationExceptionHandler {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error ->
            errors.put(error.getField(), error.getDefaultMessage()));
        return errors;
    }
}

6. 테스트하기

Postman이나 curl을 사용하여 데이터를 전송하면서 유효성 검사가 작동하는지 확인할 수 있습니다.

POST 요청 예:

  • URL: http://localhost:8080/api/users
  • Body:
    {
      "name": "",
      "email": "invalid-email",
      "password": "123"
    }

응답 예:

{
    "name": "이름은 필수 항목입니다.",
    "email": "유효한 이메일 주소를 입력해야 합니다.",
    "password": "비밀번호는 최소 6자 이상이어야 합니다."
}

반응형