View로부터 전달되는 데이터가 DB에 수용 가능한지 확인하는 과정
즉, 입력 데이터가 시스템의 요구사항을 충족하는지 확인하기 위해 유효성 검증이 필요함
검증은 크게 클라이언트와 서버 두 영역에서 가능하다
두 가지 검증 방법이 장단점이 있기 때문에, 두 방법을 적절히 섞어서 사용해야 함
일반적인 데이터 유효성 검사 로직은 아래와 같은 문제를 가지고 있음
즉, 위의 사진처럼 데이터 유효성 검사를 위해 띄어쓰기, 불필요한 문자열 처리 등과 같이 모든 유효성 케이스를 만들어서 처리해야 하고, 컨트롤러의 검증로직이 수십, 수백줄에 다다르게 될 것
-> 이는 유지보수적에 큰 어려움을 줄 것이고 실제로 중요한 비즈니스 로직은 보이지도 않게 될 것
Hibernate Validator는 Bean Validation 명세의 구현체
spring-boot-starter-validation
의존성을 추가하여 사용할 수 있음유효성 검사는 각 계층으로 데이터가 넘어오는 시점에 해당 데이터에 대한 검사를 실시
스프링부트 프로젝트에서는 계층 간 데이터 전송에 대체로 DTO 객체를 활용하고 있기 때문에 유효성 검사를 DTO 객체를 대상으로 수행하는 것이 일반적
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class ValidRequestDto {
@NotBlank
String name;
@Email
String email;
@Pattern(regexp = "01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{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;
}
각 어노테이션은 유효성 검사를 위한 조건을 설정하는데 사용됨
또한 커스텀 Validation을 추가하여, 자바 또는 스프링의 유효성 검사 어노테이션에서 제공하지 않는 검사 기능을 사용할 수 있음
// 전화번호 형식이 일치하는지 확인하는 유효성 검사 어노테이션 생성
public class TelephoneValidator implements ConstraintValidator<Telephone,String> {
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
if(value == null){
return false;
}
return value.matches("01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$");
}
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = TelephoneValidator.class)
public @interface Telephone {
String message() default "전화번호 형식이 일치하지 않습니다.";
Class[] groups() default {};
Class[] payload() default {};
}