Spring에서 JSR 303 어노테이션을 이용해 데이터 유효성검사를 진행할 수 있습니다.
보통 @NotBlank, @Size, @NotNull ...등 이미 만들어진 검증 어노테이션을 이용할 수 있지만, 자신의 목적에 맞는 검증 어노테이션을 커스텀하여 제작할 수 있습니다.
간단하게 password를 검증하는 어노테이션을 만들어보겠습니다.
1. Password Annotation 생성
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import kr.co.tlab.ppl.validator.impl.PasswordValidator;
@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Password {
String message() default "";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
public int min() default 0;
public int max() default 2147483647;
public boolean nullable() default false;
}
2. Password 검증 로직이 있는 ConstraintValidator 구현
- 비밀번호는 정해진 길이만큼 입력해야한다. (min ~ max)
- 비밀번호는 nullable 속성을 통해 Null값을 받을 수 있다. (true/false)
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import kr.co.tlab.ppl.validator.Password;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
public class PasswordValidator implements ConstraintValidator<Password, String> {
private int min;
private int max;
private boolean nullable;
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public void initialize(Password passwordValidator) {
//어노테이션 등록 시, 입력했던 Parameter를 초기화한다.
min = passwordValidator.min();
max = passwordValidator.max();
nullable = passwordValidator.nullable();
}
@Override
public boolean isValid(String password, ConstraintValidatorContext context) {
//if password is not blank
if (StringUtils.hasText(password)) {
if (password.length() < min || password.length() > max) {
addConstraintViolation(
context,
String.format("비밀번호는 %d자 ~ %d자 사이로 입력해주세요.", min, max)
);
return false;
}
}
else if (!nullable){
addConstraintViolation(
context,
"비밀번호를 입력해주세요."
);
return false;
}
return true;
}
private void addConstraintViolation(ConstraintValidatorContext context, String msg) {
//기본 메시지 비활성화
context.disableDefaultConstraintViolation();
//새로운 메시지 추가
context.buildConstraintViolationWithTemplate(msg).addConstraintViolation();
}
}
3. Member
public class Member{
private Integer id;
@NotBlank
private String account;
//Password 검증 어노테이션 등록
@Password(min = 3, max = 10, nullable = true)
private String password;
@NotBlank
private String name;
private String email;
//setter,getter 생략
}
4. ValidationTestController
@Controller
@RequestMapping(value = "")
public class ValidationTestController {
@PostMapping(value = "/member/save")
@ResponseBody
@ResponseStatus(HttpStatus.NO_CONTENT)
public void saveMember(@Valid Member member) {
... save logic
}
}
5. 비밀번호 "1" 입력 시 Response 결과
{
"timestamp": 1594282566312,
"status": 400,
"error": "Bad Request",
"errors": [{
"codes": ["Password.member.password", "Password.password", "Password.java.lang.String", "Password"],
"arguments": [{
"codes": ["member.password", "password"],
"arguments": null,
"defaultMessage": "password",
"code": "password"
}, 10, 3, true],
"defaultMessage": "비밀번호는 3자 ~ 10자 사이로 입력해주세요.",
"objectName": "member",
"field": "password",
"rejectedValue": "1",
"bindingFailure": false,
"code": "Password"
}],
"message": "Validation failed for object='member'. Error count: 1",
"path": "/member/save"
}
'IT > Spring' 카테고리의 다른 글
[Spring Boot] Ajax와 FormData 객체를 이용한 이미지 전송 (2) | 2020.08.18 |
---|---|
[Spring Boot] Ajax를 이용해 이미지 정보를 객체 단위로 전송하는 방법 (0) | 2020.08.12 |
[Spring] Ajax를 이용해 데이터를 서버로 보내는 몇 가지 방법 (0) | 2020.07.01 |
[Spring Boot] 클라이언트 디바이스 정보 확인하기 (0) | 2020.06.17 |
[Spring Boot] @ControllerAdvice을 이용한 Exception 처리 (2) | 2020.06.11 |