유효성 검사
어플리케이션의 비즈니스 로직이 올바르게 동작하려면 데이터를 사전 검증하는 작업이 필요합니다.
이를 '유효성 검사' 또는 '데이터 검증' 이라고 부르는데 이를 알아보겠습니다.
일반적인 어플리케이션 유효성 검사
문제점
- 계층별로 진행하는 유효성 검사는 검증 로직이 각 클래스별로 분산되어 있어서 관리하기가 어렵다
- 검증 로직 이외로 중복이 많아 여러 곳에 유사한 기능의 코드가 존재할 수 있다.
- 검증해야할 값이 많다면 검증하는 코드가 길어져서 코드가 복잡하고 가독성이 떨어진다.
문제 해결 방법
- 이를 해결하기 위해서 자바에서는 Bean Validation 이라는 데이터 유효성 검사 프레임워크를 제공한다.
- Bean Validation
- 어노테이션을 통해 다양한 데이터를 검증하는 기능
- 유효성 검사를 위한 로직을 DTO 같은 도메인 모델과 묶어서 각 계층에서 사용하면서 검증 자체를 도메인 모델에 얹는 방식으로 수행한다는 의미이다.
- 어노테이션을 사용한 검증 방식이기 때문에 코드의 간결함도 유지할 수 있다.
Hibernate Validator
- Hibernate Validator는 Bean Validation 명세의 구현체이다.
- 스프링부트에서는 Hibernate Validator를 유효성 검사 표준으로 채택하여 사용하고 있다.
- JSR-303 명서의 구현체로써, 도메인 모델에서 어노테이션을 통한 필드값 검증을 도와준다.
의존성 추가
Maven(pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
gradle(build.gradle)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
스프링부트의 유효성 검사
- 유효성 검사는 각 계층으로 데이터가 넘어오는 시점에 해당 데이터에 대한 검사를 실시한다.
- 스프링부트에서는 계층 간 데이터 전송을 대체로 DTO 객체를 활용하고 있기 때문에 유효성 검사를 DTO 객체를 대상으로 수행하는 것이 일반적이다.
[예시] ValidRequestDto 클래스
@Data
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ValidRequestDto {
@NotBlank
String name;
@Email
String email;
@Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\{4})[.-]?(\\d{4})$")
String phoneNumber;
@Min(value = 20) @Max(value = 40)
int age;
@Size(min = 0, max = 40)
String description;
@Positive
int count;
@AssertTrue
boolean booleanCheck;
}
문자열 검증
- @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을 포함한 양수를 허용한다.
- @Negative : 음수를 허용한다.
- @NegativeOrZero : 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 패키지 컨벤션을 따른다.
[예시] ValidationController 클래스
@RestController
@RequestMapping("/validation")
public class ValidationController {
private final Logger LOGGER = LoggerFactory.getLogger(ValidationController.class);
@PostMapping("/valid")
public ResponseEntity<String> checkValidationByValid(
@Valid @RequestBody ValidRequestDto validRequestDto) {
LOGGER.info(validRequestDto.toString());
return ResponseEntity.status(HttpStatus.OK).body(validRequestDto.toString());
}
}
[예시] Swagger를 이용한 데이터 테스트
- 유효성 검사를 통과하면 200(ok), 통과하지 못하면 400(Bad_Request) 발생
[예시] 정규식 가이드
반응형
'Spring > 스프링 이론' 카테고리의 다른 글
WebSecurityConfigurerAdapter deprecated 대체하는 방법 (0) | 2023.12.08 |
---|---|
[Spring] 트랜잭션과 @Transactional 이해하기 (0) | 2023.10.24 |
[Spring] @Controller와 @RestController의 차이 (0) | 2023.10.15 |
댓글