728x90

아이디 중복 체크 같은 커스텀이 필요한 검증을 하려면 Validator를 구현해줘야 한다.

@Valid사용으로 기본 검증에 대한 내용: https://black-mint.tistory.com/25

 

[Spring Boot] @Valid로 폼 입력값 검증하기

Entity 클래스에 @Id, @Size, @NotBlank 등을 붙여주고 Controller 클래스에서 @Valid 어노테이션을 추가적으로 사용함으로써 기본적인 검증은 가능하다. 1. 기본 form 입력값 검증하기 @Data @Entity @DynamicUpd..

black-mint.tistory.com

1. Validator 인터페이스 구현

@Component
public class MemeberValidator implements Validator {

    @Autowired
    private MemberService memberService;

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

    @Override
    public void validate(Object obj, Errors errors) {
        Member member = (Member) obj;

        if(memberService.checkUsername(member.getUsername())) {
            errors.rejectValue("username", "key", "이미 존재하는 아이디입니다.");
        }
    }
}
  • validator 패키지 추가 후 Validator 인터페이스를 구현
  • 검증이 필요한 Entity 클래스를 supports에 작성
  • validate에서 View -> Controller -> MemberValidator로 넘어온 member 객체를 통해 값의 검증을 시작
  • errors.rejectValue("에러 필드명", "키값", "키 값이 없을 때 사용할 메세지") 로 구성된다.

2. Controller 적용

@PostMapping("/join")
public String join(@Valid Member member, BindingResult bindingResult){
    memeberValidator.validate(member, bindingResult);

    if(bindingResult.hasErrors()) {
        return "/account/joinForm";
    }

    String encPwd = memberService.pwdEncoding(member.getPassword());
    member.setPassword(encPwd);

    memberService.join(member);

    return "redirect:/loginForm";
}
  • 컨트롤러에서 구현한 Validator에 Member와 BindingResult를 전달해준다.

3. View 적용

<form th:action="@{/join}" method="post" th:object="${member}">          
          <div class="form-floating mt-4">
            <input type="text" class="form-control" th:field="*{username}" th:classappend="${#fields.hasErrors('username')} ? 'is-invalid'" id="floatingInput" placeholder="Username">
            <label for="floatingInput">Username</label>
            <div th:if="${#fields.hasErrors('username')}" th:errors="*{username}" id="validationServer03Feedback" class="invalid-feedback text-start">
              Username Error
            </div>
          </div>
          <div class="form-floating">
            <input type="password" class="form-control mt-2" th:field="*{password}" th:classappend="${#fields.hasErrors('password')} ? 'is-invalid'" id="floatingPassword" placeholder="Password">
            <label for="floatingPassword">Password</label>
            <div th:if="${#fields.hasErrors('password')}" th:errors="*{password}" id="validationServer03Feedback" class="invalid-feedback text-start" style="margin-bottom: 8px;">
              Password Error
            </div>
          </div>
          <div class="form-floating">
            <input type="email" class="form-control" th:field="*{email}" th:classappend="${#fields.hasErrors('email')} ? 'is-invalid'" id="floatingPassword" placeholder="Email">
            <label for="floatingPassword">example@board.com</label>
            <div th:if="${#fields.hasErrors('email')}" th:errors="*{email}" id="validationServer03Feedback" class="invalid-feedback text-start" style="margin-top: 8px;">
              Email Error
            </div>
          </div>
      
          <div class="checkbox mb-3">
          </div>
          <button class="w-100 btn btn-lg btn-primary mt-2" type="submit">Get started!</button>
          <a type="button" class="w-100 btn btn-lg btn-primary mt-2" th:href="@{/}">exit</a>
        </form>
  • 타임리프의 th:if가 달린 3개의 div 태그에서 에러를 출력해준다.
  • th:if=${#fields.hasErrors('필드명')} : 에러가 발생한 경우 true 값을 반환하여 div태그를 표시해준다.
  • form 태그의 th:object="{member}" : GetMapping 때 전달받은 Member의 키 값을 넣어 전달 받은 객체
  • "*{username}" :  위 설명을 참고해서 Member.getUsername()을 View에서 사용할 수 있도록 한 값이다. -> ${member.username} 과 같다고 생각!
  • th:errors="*{password}" : password에 대한 에러 내용을 표시해준다.

+ Recent posts