Validation을 다룰예정..
먼저 validation이란?
흔히 만나는 NPE(null pointer exception)이라던가
회원가입으로 String값 (ex. moon123) 을 넣어달라고 헀는데
맘대로 123을 비민번호로 넣는다던가 할때 validation을 통해
예외를 처리하고 방지한다
간단한 방법으로는 @Annotation을 dto에 적어서 구현이 가능하다
종류
@Size null 불가능
@NotNull null, “” 불가능
@NotBlank null, “”, “ “ 불가능
@Past 과거 날짜
@PastOrPresent 오늘 or 과거 날짜
@Future 미래 날짜
@FutureOrPresent 오늘 or 미래 날짜
@Pattern 정규식 적용
@Max 최대값
@Min 최소값
@AssertTrue/False 별도 로직 적용
@Valid 객체 검증(Validation) 실행
중간에 @Pattern을 사용하는 예시를 가져와보았다
// 전화번호 예시
@Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$")
private String phoneNumber;
하지만 이렇게 하면 컬럼별로 적용하기 때문에
만약 비밀번호에는 아이디가 포함되면 안된다 같은 요구사항에는
대응할 수 없기에 직접 어노테이션을 구현하여 class에 붙이는 것도 가능하다
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
먼저 gradle에 추가해주고
@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidPassword {
Class<?>[] groups() default {};
String message() default "닉네임을 포함하지 않는 4자 이상 비밀번호를 입력하세요.";
Class<? extends Payload>[] payload() default {};
}
여기서 Target 어노테이션을 어떻게 하느냐에 따라 class에 붙일수도 컬럼에 붙일수도 있다 해당 내용은 이전 포스트로!
public class PasswordValidator implements ConstraintValidator<ValidPassword, SignRequestDto> {
@Override
public void initialize(ValidPassword constraintAnnotation) {
}
@Override
public boolean isValid(SignRequestDto signRequestDto, ConstraintValidatorContext context) {
if (signRequestDto.password() == null || signRequestDto.username() == null) {
return false;
}
boolean isLengthSufficient = signRequestDto.password().length() >= 4;
boolean isNicknameIncluded = signRequestDto.password().contains(signRequestDto.username());
return isLengthSufficient && !isNicknameIncluded;
}
}
ValidPassord를 구현했다면 상속받아서 로직을 만든다
1. password의 길이를 확인하고
2. password에 nickname이 포함되는지(contains)확인하여
둘다 만족하고 있는지 return한다
@ValidUsername
@ValidPassword
public record SignRequestDto(
String username,
String password
) {
}
구현한 어노테이션을 dto에 달아주면 완성
물론! controller에 @Valid signRequestDto와 같이
어노테이션을 달아주는것 잊지 않기..