Spring Boot에서 Validation은 사용자가 제출한 데이터를 검증하는 기능으로, 데이터 무결성을 보장하고 오류를 사전에 방지하기 위해 사용됩니다. 주로 Java Bean Validation(JSR 380, Hibernate Validator)과 함께 사용됩니다. Validation은 입력 데이터를 간단하게 검증할 수 있도록 도와주며, 주로 컨트롤러 계층에서 활용됩니다.
Spring Boot에서는 기본적으로 Hibernate Validator를 포함하고 있습니다. 추가적인 의존성 없이 바로 사용할 수 있습니다.
Maven 프로젝트라면 아래 의존성을 확인:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
Java Bean Validation의 다양한 어노테이션을 사용하여 필드 검증 규칙을 설정합니다.
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class UserRequest {
@NotBlank(message = "Username은 필수 항목입니다.")
@Size(min = 3, max = 15, message = "Username은 3자 이상 15자 이하여야 합니다.")
private String username;
@NotBlank(message = "Email은 필수 항목입니다.")
@Email(message = "유효한 이메일 형식이 아닙니다.")
private String email;
@NotBlank(message = "비밀번호는 필수 항목입니다.")
@Size(min = 6, message = "비밀번호는 최소 6자 이상이어야 합니다.")
private String password;
// Getter, Setter
}
@Valid
또는 @Validated
어노테이션을 사용하여 검증을 활성화합니다.
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<String> createUser(@Valid @RequestBody UserRequest userRequest) {
// Validation 성공 시 처리 로직
return ResponseEntity.ok("User created successfully!");
}
}
Validation 실패 시 MethodArgumentNotValidException이 발생합니다. 이를 처리하기 위해 @ControllerAdvice와 @ExceptionHandler를 활용하여 예외를 처리할 수 있습니다.
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
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);
}
}
@NotNull
: 값이 null
이 아니어야 함.@NotEmpty
: 문자열, 배열, 컬렉션 등이 비어 있지 않아야 함.@NotBlank
: 공백 문자를 제외한 값이 비어 있지 않아야 함.@Size
: 문자열, 배열, 컬렉션 등의 크기를 제한.@Min
/ @Max
: 숫자 값의 최소 및 최대값.@Pattern
: 정규 표현식을 활용한 값 검증.@Email
: 유효한 이메일 형식.@Validated
어노테이션과 그룹을 사용하여 조건에 따라 다른 Validation을 적용할 수 있습니다.
public class UserRequest {
public interface Create {}
public interface Update {}
@NotBlank(groups = Create.class)
private String username;
@NotBlank(groups = {Create.class, Update.class})
@Email(groups = {Create.class, Update.class})
private String email;
}
컨트롤러에서 특정 그룹을 지정해 Validation을 활성화합니다:
@PostMapping
public ResponseEntity<String> createUser(@Validated(UserRequest.Create.class) @RequestBody UserRequest userRequest) {
return ResponseEntity.ok("User created!");
}
커스텀 검증 로직이 필요한 경우, 새로운 Validation 어노테이션을 정의하고 이를 처리하는 Validator를 작성합니다.
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Constraint(validatedBy = CustomValidator.class)
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomConstraint {
String message() default "Custom validation failed";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
public class CustomValidator implements ConstraintValidator<CustomConstraint, String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && value.startsWith("Valid");
}
}
public class CustomRequest {
@CustomConstraint(message = "Value must start with 'Valid'")
private String customField;
}
Spring Boot Validation은 데이터 검증을 간편하게 처리하면서도, 확장성과 유지보수성을 높여줍니다. 다양한 상황에 따라 검증 로직을 적용하고, Validation 실패에 대한 처리를 유연하게 구성할 수 있습니다.
추가 학습 자료
-[Spring Boot] Validation 적용, @Valid로 유효성 검사하기 - by coco3o
-Using the Spring Boot Validation Starter
-[Spring] 스프링 부트 값 검증(Validation) 가이드