BE/Spring & Spring Boot

[Spring Boot] Validation 유효성 검사

baek-dev 2024. 12. 30. 13:02

애플리케이션에서 입력값이 예상한 조건에 부합하는지 확인하는 과정

 

필요한 이유

1. 데이터 무결성 보장

  • 잘못된 입력값으로 인해 발생할 수 있는 데이터베이스나 시스템 오류 방지

2. 보안 강화

  • 유효하지 않은 데이터를 허용하지 않아 악의적인 요청 차단

3. 사용자 경험 향상

  • 잘못된 데이터를 입력했을때 즉시 피드백 제공

Spring Boot에서 Validation 사용하기

1. 의존성 추가

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

 

2. 주요 어노테이션

어노테이션 설명
@NotNull 값이 null이 아니어야 함
@NotEmpty 값이 null이 아니고, 빈 문자열이 아니어야 함
@NotBlank 값이 null, 빈 문자열, 공백만 포함하지 않아야 함
@Size 문자열, 배열, 컬렉션의 크기 제한
@Min / @Max 숫자 값의 최소 / 최대값 설정
@Positive 숫자가 양수여야 함
@Negative 숫자가 음수여야 함
@Email 이메일 형식이어야 함
@Pattern 정규식 패턴을 만족해야 함
@Digits 정수와 소수 자릿수 제한
@Future / @Past 날짜가 미래 / 과거이어야 함

 

3. Validation 예제

DTO 클래스에서 Validation

사용자가 전달한 입력 데이터를 검증하기 위해 DTO (Data Transfer Object)에 Validation 어노테이션을 사용

import jakarta.validation.constraints.*;

public class UserDTO {

    @NotBlank(message = "Name is mandatory")
    private String name;

    @Email(message = "Email should be valid")
    private String email;

    @NotNull(message = "Age is mandatory")
    @Min(value = 18, message = "Age must be at least 18")
    private Integer age;

    // Getters and Setters
}

 

컨트롤러에서 Validation 처리

@Valid 애너테이션을 사용하여 DTO의 값을 자동 검증한다. 검증 실패 시 예외가 발생한다.

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

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

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO) {
        // 검증 성공 시 로직 실행
        return ResponseEntity.ok("User created successfully");
    }
}

 

Validation 실패 처리

validation 실패시 MethodArgumentNotValidException이 발생하며, 이를 처리하려면 @ExceptionHandler 를 사용할 수 있다

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.bind.MethodArgumentNotValidException;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

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

커스텀 Validation 만들기

1. 어노테이션 정의

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = NameValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidName {
    String message() default "Invalid name";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

 

2. validator 구현

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

public class NameValidator implements ConstraintValidator<ValidName, String> {

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        // 이름은 알파벳으로만 구성되어야 함
        return value != null && value.matches("[a-zA-Z]+");
    }
}

 

3. 어노테이션 적용

public class UserDTO {
    
    @ValidName(message = "Name must only contain alphabets")
    private String name;

    // other fields
}

Validation 정리

 

1. Validation의 역할

  • 데이터를 검증하여 애플리케이션의 안정성과 무결성을 보장

 

2. 주요 애너테이션

  • @NotNull, @Email, @Size, @Pattern, @Min, @Max 등

 

3. 컨트롤러와 연동

  • DTO 클래스에 애너테이션 적용 → 컨트롤러에서 @Valid 사용

 

4. 실패 처리

  • Spring Boot의 예외 처리 메커니즘으로 유효성 검사 실패를 핸들링

 

5. 확장성

  • 커스텀 Validator를 정의하여 유연한 검증 로직 추가 가능

 

 

 

 

출처 : ChatGPT

'BE > Spring & Spring Boot' 카테고리의 다른 글

[Spring Boot, JPA] 관련 어노테이션  (0) 2025.01.01
[Spring Boot] 관련 어노테이션  (0) 2025.01.01
[Spring Boot] Thymeleaf 타임리프  (0) 2024.12.29
[Spring Boot] Page  (0) 2024.12.27
[Spring Boot, Java] Cascade  (0) 2024.12.26