Srping Validation
Spring에서는 AOP와 같은 방식으로 더 편리하게 유효성검사를 할 수 있다.
Validated
스프링에서는 유효성검사에 진입하게되는 지점에 @Validated라는 애노테이션을 사용하는 방법을 제공한다.
필요한 클래스나 메소드에 @Validated 어노테이션을 추가해서 사용한다.
@Service
@Validated
public class UserService{
public User add(@NotNull User user){
}
}
만약 제약조건에 위반되면 ConstraintViolationException이 발생하게 된다.
(※ @ControllerExceptionHanlder를 사용하여 요긴하게 써먹을 수 있음. ConstrainoViolationException에서 getConstraintViolations를 사용하여 Set<ConstraintViolation<T>>를 얻을 수 있다.)
@Validate를 사용하기 위해선, MethodValidationPostProcessor를 빈으로 등록해야 한다. SpringBoot에서는 ValidationAutoConfiguration에 이미 MethodValidationPostProcessor가 정의되어 있으므로 따로 선언할 필요는 없다.
Spring MVC에서 유효성 검사
Spring 내부에서 사용하는 Validator(org.springframework.validation.Validator) 인터페이스를 살펴보자.
public interface Validator {
// 이 검사기가 지원하는 클래스인지를 판단
boolean supports(Class<?> clazz);
// 유효성검사를 진행, errors 객체에 상태를 저장한다.
void validate(@Nullable Object target, Errors errors);
}
Spring MVC에서는 데이터 바인딩 시점에 유효성 검사를 실시한다. 바인딩에 실패한 경우 MethodArgumentNotValidException이 발생하게 된다.
유효성 검사 결과를 사용하려면 BindingResult 객체를 주입받아서 사용할 수 있으며, 이 객체에는 유효성 검사를 실행한 결과 정보가 담겨져 있다.
@Slf4j
@RestController
public class UserController {
// 바인딩 실패시 MethodArgumentNotValidException 발생
@PostMapping("/api/user")
public void addUser(@Valid @RequestBody User user){
}
// 유효성 검사 실패시, BindingResult 객체에서 결과정보 획득 가능
@PostMapping("/api/user")
public void addUser(@Valid @RequestBody User user, BindingResult bindingResult){
if(bindingResult.hasErrors()){
for(ObjectError obj : bindingResult.getAllErrors()){
log.info("message : {}", obj.getDefaultMessage());
log.info("code : {}", obj.getDefaultMessage());
log.info("object name : {}", obj.getObjectName());
}
}
}
}
Validator 커스터마이징
JSR-303, JSR-380 스펙으로 유효성 검사를 한 후 추가적으로 다른 유효성 검사를 하고자 할때 사용한다.
Validator 인터페이스 구현
supports : 유효성 검사할 데이터를 가지고 있는 객체가 유효성 검사가 가능한지 확인
validate : 유효성을 검사하는 메서드
public class UserValidator implements Validator { @Override public boolean supports(Class<?> aClass) { return User.class.isAssignableFrom(aClass); } @Override public void validate(Object o, Errors errors) { } }
Validator를 컨트롤러에 등록
사용할 Validator가 하나면 setValidator, 한 개 이상이면 addValidators 메서드를 사용한다.@InitBinder protected void initBinder(WebDataBinder binder){ binder.setValidator(new UserValidator()); }
ValidateUtils
⇒ 지정된 값에 대해 유효성 검사를 하는 메서드들이 존재함.
- rejectIfempty(error 객체, 프로퍼티 이름, 코드이름)
- rejectIfEmptyOrWhitespace(error 객체, 프로퍼티 이름, 코드이름)
rejectValue
⇒ 유효성 조건을 직접 만들어 검사할 때 사용
- rejectValue(프로퍼티 이름, 코드 이름, 디폴트 메세지)
입력값에 문제가 있다면 error 객체에 오류정보를 저장한다. 사용할 오류 메시지는 "코드이름.객체이름.프로퍼티이름"으로 구성됨
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return User.class.isAssignableFrom(aClass);
}
@Override
public void validate(Object o, Errors errors) {
User user = (User) o;
int age = user.getAge();
String adminNumber = user.getAdminNumber();
if(age<0){
errors.rejectValue("age", "positive", "나이는 0 이상이어야 합니다.");
}
if(StringUtils.isEmpty(adminNumber)){
errors.rejectValue("adminNumber", "isEmpty");
}
}
}
위의 메소드에서 코드 이름이란, MessageSource에 등록된 코드이름을 뜻한다.
'프로그래밍 노트 > SPRING BOOT' 카테고리의 다른 글
[Spring Boot] RedisCluster 연동 & RedisTemplate 적용 (feat. AutoConfiguration) (0) | 2024.10.22 |
---|---|
Validation 알아보기_1(Hibernate Validator) (0) | 2021.01.09 |
[Spring Boot] 외부설정하기 (externalized configuration) (2) | 2019.11.18 |
@Conditional, @ConditionalOnXXX (0) | 2019.11.18 |
[Spring Boot] Custom한 배너를 만들어보자! (0) | 2019.11.05 |