본문 바로가기

스프링

Validator - 스프링부트

출처 및 참고
https://velog.io/@jyleedev/%EC%9C%A0%ED%9A%A8%EC%84%B1%EA%B2%80%EC%82%AC#2-validator-%EA%B5%AC%ED%98%84%EC%B2%B4-abstractvalidator

 

 

1. Validator 의존성주입

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation

 

2. validator 인터페이스 받기

 

public abstract class BaseValidator<T> implements Validator {

  @Override
  public boolean supports(Class<?> clazz) {
    return true;
  }

  @Override
  @SuppressWarnings("unchecked")  // 미확인 오퍼레이션 경고 억제
  public void validate(Object target, Errors errors) {
    try {
      doValidate((T) target,errors);  // 여기서 경고 나올텐데 SuppressWarning 써주면 없어짐
    } catch (IllegalStateException e) {
      log.error("중복 검증",e);
      throw e;
    }
  }

  protected abstract void doValidate(final T dto,final Errors errors);
}

supports() - 검증하려는 클래스 타입 체크 → 추상클래스로 다른 클래스에도 적용하기 위해서 true로 고정

@Override
public boolean supports(Class<?> clazz) {
  return MeberDto.class.equals(clazz);
}

원래는 위와같은 방식으로 @Validated 애노테이션이 붙은 객체 클래스가 동일한지 검사하여 동일하다면 실행되는 형식

 

validate() - 실제로 검증이 일어나는 메소드doValidate() - 여러 validator에서 인터페이스로 사용하기 위한 메소드

 

3. 실제 사용할 Validator 만들기

@Component
@RequiredArgsConstructor
public class CheckIdValidator extends BaseValidator<MemberDto>{
  private final MemberRepository memberRepository;

  @Override
  protected void doValidate(MemberDto dto, Errors errors) {
    if (memberRepository.existsById(dto.getId())) {
      errors.rejectValue("id","아이디 중복 오류","이미 사용중인 아이디");
    }
  }
}

컴포넌트로 등록

rejectValue - Errors가 제공하는 메소드 → 필드에 대한 에러 및 에러코드, 에러 메시지 추가(메시지는 디폴트 메시지가 없을때 사용)

 

 

4. @InitBinder / 컨트롤러 작성

@Controller
@RequiredArgsConstructor
public class MemberController {
    private final CheckIdValidator checkIdValidator;

    @PostMapping("join")
    public String join(@Validated @ModelAttribute MemberDto memberDto,
                       BindingResult bindingResult, Model model) {

        if (bindingResult.hasErrors()) {
            model.addAttribute("memberDto",memberDto);

            Map<String,String> map = new HashMap<>();

            for (FieldError error : bindingResult.getFieldErrors()) {
                map.put("valid_"+error.getField(),error.getDefaultMessage());
                log.info("error message : "+error.getDefaultMessage());
            }

            model.addAllAttributes(map);

            return "member/join";
        } else {
            // 아이디 중복 오류 안났을때 로직
        }
    }

    @InitBinder
    public void validatorBinder(WebDataBinder binder) {
        binder.addValidators(checkIdValidator);
    }
}

@InitBinder - 사용할 Validator를 정의, 변경해주는 어노테이션

WebDataBinder - http요청 정보를 바인딩할때 사용되는 객체 / 파라미터 바인딩 역할

binder에 검증기 추가하여 검증 진행

 

중요

You must declare an Errors, or BindingResult argument immediately after the validated method argument.

검증할 객체 바로 뒤에 BindingResult / Error 객체가 선언되어야함

안그러면 검증 실패시 whitelabel 에러페이지로 가게됨

https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments

 

 

 

 

 

'스프링' 카테고리의 다른 글

Rest Template  (0) 2022.10.18
jstl 적용하기  (0) 2022.03.19
HttpServletRequest  (0) 2022.01.12