개발/Spring

Spring Validation 어노테이션, 구현 방법

피터JK 2025. 2. 13. 10:25
728x90

1. Spring Validation 기본 어노테이션

Spring Boot에서는 javax.validation (Jakarta EE) 표준을 기반으로 검증 기능을 제공합니다.
아래 어노테이션들은 javax.validation.constraints 패키지에서 제공됩니다.

1.1 기본 검증 어노테이션

어노테이션  설명
@NotNull 필드 값이 null이면 안 됨 (""은 허용)
@NotEmpty 필드 값이 null이거나 빈 문자열("")이면 안 됨
@NotBlank 필드 값이 null, 빈 문자열(""), 공백(" ")이면 안 됨
@Size(min = x, max = y) 문자열, 컬렉션의 크기를 지정된 범위 내로 제한
@Min(x) 숫자 값이 x 이상이어야 함
@Max(x) 숫자 값이 x 이하이어야 함
@Positive 숫자 값이 0보다 커야 함
@PositiveOrZero 숫자 값이 0 이상이어야 함
@Negative 숫자 값이 0보다 작아야 함
@NegativeOrZero 숫자 값이 0 이하이어야 함
@Pattern(regexp = "정규표현식") 정규식을 이용해 문자열 패턴을 검증
@Email 이메일 형식인지 검증
@Future 날짜가 현재보다 미래여야 함
@FutureOrPresent 날짜가 현재 또는 미래여야 함
@Past 날짜가 현재보다 과거여야 함
@PastOrPresent 날짜가 현재 또는 과거여야 함
@Digits(integer = x, fraction = y) 정수 및 소수점 자리수를 제한

1.2 컬렉션 및 배열 검증

 

어노테이션 설명
@Size(min = x, max = y) 컬렉션(List, Set, Map) 및 배열의 요소 개수 검증

2. Spring Boot에서 사용하는 추가적인 검증 어노테이션

Spring Boot에서는 org.springframework.validation.annotation.Validated 및 기타 검증 어노테이션을 활용할 수 있습니다.

2.1 @Valid

  • javax.validation.Valid
  • 필드나 매개변수에 대한 재귀적 검증을 수행
  • DTO 내부에 또 다른 DTO가 있는 경우 내부 필드까지 검증 가능
public class Address {
    @NotBlank
    private String street;

    @NotBlank
    private String city;
}
public class User {
    @NotBlank
    private String name;

    @Valid  // Address 내부 필드도 검증됨
    private Address address;
}

2.2 @Validated

  • org.springframework.validation.annotation.Validated
  • @Valid와 비슷하지만 타입별 검증 그룹(Group Validation) 기능을 제공
@Validated
@RestController
public class UserController {

    @PostMapping("/users")
    public ResponseEntity<String> createUser(@RequestBody @Valid User user) {
        return ResponseEntity.ok("User created");
    }
}

3. 검증 그룹 사용 (@Validated + groups)

@Validated를 사용하면 특정 검증 그룹을 지정할 수 있습니다.

public interface CreateGroup {}
public interface UpdateGroup {}
public class User {
    @NotBlank(groups = CreateGroup.class)
    private String name;

    @Email(groups = {CreateGroup.class, UpdateGroup.class})
    private String email;
}

컨트롤러에서 특정 그룹을 지정해 검증 가능:

@Validated(CreateGroup.class)
@PostMapping("/users")
public ResponseEntity<String> createUser(@RequestBody @Valid User user) {
    return ResponseEntity.ok("User created");
}

4. 커스텀 검증 어노테이션 만들기

기본 검증 어노테이션 외에도 직접 검증 어노테이션을 만들 수 있습니다.

@Documented
@Constraint(validatedBy = CustomValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomValidation {
    String message() default "유효하지 않은 값입니다.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
public class CustomValidator implements ConstraintValidator<CustomValidation, String> {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value != null && value.startsWith("A");
    }
}

사용법:

public class User {
    @CustomValidation
    private String username;
}

5. Controller에서 검증 예외 처리

Spring Boot에서는 @ExceptionHandler를 활용하여 검증 오류를 처리할 수 있습니다.

@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 ResponseEntity.badRequest().body(errors);
    }
}

6. Spring Boot Validator 직접 사용

Spring에서는 Validator 인터페이스를 직접 구현하여 검증할 수도 있습니다.

@Component
public class UserValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        User user = (User) target;
        if (user.getName().length() < 3) {
            errors.rejectValue("name", "name.short", "이름은 3글자 이상이어야 합니다.");
        }
    }
}

컨트롤러에서 @InitBinder로 적용:

@InitBinder
protected void initBinder(WebDataBinder binder) {
    binder.setValidator(new UserValidator());
}

7. JSP에서 검증 오류 출력하기

Spring Boot와 JSP를 사용할 때 검증 오류 메시지를 출력하는 방법은 다음과 같습니다.

7.1 Controller 설정

@PostMapping("/register")
public String register(@ModelAttribute("user") @Valid User user, BindingResult result) {
    if (result.hasErrors()) {
        return "register"; // 검증 오류가 있으면 다시 입력 폼으로 이동
    }
    return "redirect:/success";
}

7.2 JSP에서 오류 메시지 출력

<form action="/register" method="post">
    이름: <input type="text" name="name" value="${user.name}" />
    <span style="color: red;">${errors['name']}</span>
    <br/>
    이메일: <input type="text" name="email" value="${user.email}" />
    <span style="color: red;">${errors['email']}</span>
    <br/>
    <input type="submit" value="등록" />
</form>

Controller에서 ModelBindingResult를 담아 JSP로 전달하면 검증 오류 메시지를 쉽게 표시할 수 있습니다.


8. 정리

Spring Boot의 검증 관련 어노테이션들은 크게 다음과 같이 분류됩니다:

  1. 기본 제공 검증 어노테이션: @NotNull, @NotEmpty, @Size, @Min, @Max, @Email, @Pattern 등
  2. 객체 검증: @Valid (재귀적 검증), @Validated (그룹 검증)
  3. 커스텀 검증: 사용자 정의 검증 어노테이션
  4. 검증 예외 처리: @ExceptionHandler 활용하여 검증 오류 응답 처리
  5. Validator 인터페이스 활용: Validator 직접 구현

Spring Boot의 검증 기능을 적절히 조합하면 유효성 검사를 효과적으로 수행할 수 있습니다. 

728x90