특정 애플리케이션의 비즈니스 로직이 정상적으로 동작하기 위해서 여러가지 요건이 필요하겠지만, 그 중 하나는 올바른 입력값을 위한 유효성 검증이 필요하다. 제대로 된 입력값을 검증하지 않고 입력받게 된다면 의도치 않은 에러나 버그가 발생할 수 있고 데이터의 정확성인 일관성을 보장하기 어렵다.
1. Spring Boot에서의 Validation
자바에서는 javax.validation(혹은 jakarta.validation) 패키지에 정의된 Bean Validation API를 기반으로 하며 다양한 어노테이션 기반으로 필드 수준의 검증을 쉽게 수행할 수 있다. Spring Boot 에서는 이 Bean Validation의 구체적인 구현체로 Hibernate Validator를 검사 표준으로 채택해 사용하고 있다. spring boot에서 사용하기 위해서는 아래와 같은 의존성을 추가해야 하며, spring boot initializer를 활용한다면 validation이라는 이름으로 추가할 수 있다.
implementation 'org.springframework.boot:spring-boot-starter-validation'
주로 엔티티나 DTO 같은 도메인 모델에 적용 후 컨트롤러에서 그 검증을 일반적으로 수행한다. 아래는 그 예시이다.
import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class User {
@NotBlank(message = "이름은 필수 입력 항목입니다.")
private String name;
@NotNull(message = "나이는 필수 입력 항목입니다.")
@Min(value = 18, message = "나이는 18세 이상이어야 합니다.")
private Integer age;
@Email(message = "유효한 이메일 형식이어야 합니다.")
private String email;
// Getter 및 Setter 생략
}
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public String createUser(@Valid @RequestBody User user, BindingResult result) {
if (result.hasErrors()) {
return result.getAllErrors().stream()
.map(ObjectError::getDefaultMessage)
.collect(Collectors.joining(", "));
}
// 실제 사용자 생성 로직 (생략)
return "사용자가 성공적으로 생성되었습니다.";
}
}
컨트롤러와 엔티티에서 정의해 주로 사용하며 계층 간(Controller, Service 등) 데이터 전송 시에도 활용 가능하다. 다만 검증을 하기 위해서는 컨트롤러의 @Valid 어노테이션을 지정해야 그 객체에 대한 검사를 수행하므로 이 점을 유의해야한다.
2. Validation의 주요 어노테이션
유효성 검증 시 사용하는 주된 어노테이션들은 다음과 같다. 상황에 맞게 적절하게 필드에 적용해 사용하면 된다.
문자열 검증
- @Null : null 값만 허용한다.
- @NotNull : null을 허용하지 않는다. “”, “ “는 허용한다.
- @NotEmpty : null, ““을 허용하지 않는다. “ “는 허용한다.
- @NotBlank : null, “”, “ “을 허용하지 않는다.
최댓값 / 최솟값 검증
- BigDecimal, BigInteger, int, long 등의 타입을 지원한다.
- @DemicalMax(value = "$numberString") : $numberString 보다 작은 값을 허용한다.
- @DemicalMin(value = "$numberString") : $numberString 보다 큰 값을 허용한다.
- @Min(value = $number) : $number 이상의 값을 허용한다.
- @Max(value = $number) : $number 이하의 값을 허용한다
값의 범위 검증
- BigDecimal, BigInteger, int, long 등의 타입을 지원한다.
- @Positive : 양수를 허용한다.
- @PositiveOrZero : 0을 포함한 양수를 허용한다.
- @Nagative : 음수를 허용한다.
- @NagetiveOrZero : 0을 포함한 음수를 허용한다.
시간에 대한 검증
- Date, LocalDate, LocalDateTime등의 타입을 지원한다.
- @Future : 현재보다 미래의 날짜를 허용한다.
- @FutureOrPresent : 현재를 포함한 미래의 날짜를 허용한다
- @Past : 현재보다 과거의 날짜를 허용한다.
- @PastOrPresent : 현재를 포함한 과거의 날짜를 허용한다.
이메일 검증
- @Email : 이메일 형식을 검사한다. ““는 허용한다.
자릿수 범위 검증
- BigDecimal, BigInteger, int, long 등의 타입을 지원한다.
- @Digits(integer = $number1, fraction = $number2) : $number1의 정수 자릿수와 $number2의 소수 자릿수를 허용한다.
Boolean 검증
- @AssertTrue : true인지 체크한다. null값은 체크하지 않는다.
- @AssertFalse : false인지 체크한다. null값은 체크하지 않는다.
문자열 길이 검증
- @Size(min = $number1, max = $number2) : $number1 이상 $number2 이하의 범위를 허용한다.
정규식 검증
- @Pattern(regexp = "$expression") : 정규식을 검사한다 정규식은 자바의 java.util.regex.Pattern 패키지의 컨벤션을 따른다.
지금까지 기초적인 Validation에 대해서 확인했다. 이외에도 Boolean 검증과 커스텀 validation을 통해서 필요한 상황에 좀 더 유연하게 적용하는 방식도 있는데 이는 다음에 알아보자.
참고 자료
스프링 부트 핵심 가이드 6주차: 10장
@BindingResult , @Valid , @Validate , @RestControllerAdvice , @ExceptionHandler , ConstraintValidator
velog.io
'Web Programming > Spring Boot' 카테고리의 다른 글
[Spring Boot] IoC와 DI (1) | 2024.09.06 |
---|---|
[Spring Boot] Spring MVC의 DispatcherServlet (0) | 2024.08.28 |