ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 패스워드 검증 추가하기
    프로젝트/게시판 프로젝트 2024. 10. 23. 16:35
    1. 직접 검증
    2. BindingResult
    3. 애노테이션 사용

     

    직접검증

    • HashMap을 이용하여, error를 담고 ModelAttribute로 반환
    • thymeleaf의 조건문과 삼항문을 이용하여, error 인 경우와 정상인경우 렌더링
    //[Controller]
    
    
           Map<String,String> errors = new HashMap<>();
           
           if ( member.getPasswd() != null && member.getPasswd().length() >= 8 ){
                if (member.getPasswd().matches("[a-zA-Z]+")){
                    errors.put("passwd", "비밀번호는 숫자와 특수문자를 포함해야합니다.");
                }else if (member.getPasswd().matches("[0-9]+")) {
                    errors.put("passwd", "비밀번호는 문자와 특수문자를 포함해야합니다.");
                }else if (member.getPasswd().matches("[a-zA-Z0-9]+")){
                    errors.put("passwd", "비밀번호는 특수문자를 포함해야합니다.");
                }
            }else{
                errors.put("passwd", "비밀번호는 문자,숫자,특수문자를 포함하여 8자이상이어야합니다.");
            }
            
            
            if(!errors.isEmpty()){
                model.addAttribute("errors",errors);
                return "member/member-form";
            }
    [Thymeleaf]

    <input 태그>
    th:class="${errors?.containsKey('[모델attribute값]')} ? '[오류형태]' : '[정상형태]'"

    <div 태그>
    th:if = "${errors?.containsKey('[모델 attribute값]')}" th:text="${errors'[모델 attribute값]'}"
    (* th:if 는 model.addAttribute로 값이 넘어왔는지 확인)
    (* th:text는 값이 넘어왔을경우, 해당 MAP에 기록되어있는 오류메시지)

    <!-- [html] -->
    
    <div class="form-group mb-3">
        <label for="passwd">Password:</label>
        <input type="password" id="passwd" th:field="*{passwd}" th:class="${errors?.containsKey('passwd')}? 'form-control field-error':'form-control'", class="form-control">
        <div class="field-error" th:if="${errors?.containsKey('passwd')}" th:text="${errors['passwd']}"> 비밀번호 입력 오류 </div>
    </div>

     

    BindingResult

    • BindingResult는 @ModelAttribute 뒤에 바로 인자값으로 들어와야함 (spring 인지 가능)
      • BindingResult의 경우, Model에 자동으로 포함됨
    • FieldError를 통해서, 에러값 넣기 (HashMap역할)
      • FieldError(String ObjectName, String Field, String DefaultMessage) {}
        • objectName : @ModelAttribute 이름
        • field : 오류가 발생한 필드 이름
        • defaultMessage : 오류 기본 메시지
      • FieldError(String ObjectName, String field, Object rejectedValue, boolean bindingFailure, @Nullable String[] codes, @Nullable Object[] argument, @Nullable String defaultMessage(
        • ObjectName : 오류가 발생한 객체 이름
        • field : 오류 필드
        • rejectedValue : 사용자가 입력한 값
        • bindingFailure : 타입 오류 같은 바인딩 실패인지 검증실패인지 구분값
        • codes : 메시지 코드
        • argument : 메시지에서 사용하는 인자
        • defaultMessage : 기본 오류 메시지
      • 추가) ObjectError(String objectName, String DefaultMessage){}
        • objectName : @ModelAttribute 이름
        • defaultMessage : 오류기본메시지
        • 특정필드 이외의 오류가 필요한경우 사용
    • thymeleaf의 th:errorclass 및 th:errors를 이용하여 표현
    public String registryMember(@ModelAttribute Member member, BindingResult bindingResult){       
    
    //...
           if ( member.getPasswd() != null && member.getPasswd().length() >= 8 ){
                if (member.getPasswd().matches("[a-zA-Z]+")){
                    bindingResult.addError(new FieldError("member","passwd", "비밀번호는 숫자와 특수문자를 포함해야합니다."));
                }else if (member.getPasswd().matches("[0-9]+")) {
                    bindingResult.addError(new FieldError("member", "passwd", "비밀번호는 문자와 특수문자를 포함해야합니다"));
                }else if (member.getPasswd().matches("[a-zA-Z0-9]+")){
                    bindingResult.addError(new FieldError("member","passwd", "비밀번호는 특수문자를 포함해야합니다 "));
                }
            }else{
                bindingResult.addError(new FieldError("member","passwd", "비밀번호는 문자,숫자,특수문자를 포함하여 8자이상이어야합니다."));
            }
    
            if (bindingResult.hasErrors()){
                return "member/member-form";
            }
            
    //... 성공시나리오
    }
    th:errors : 해당 필드에 오류가 있는경우 태그 출력 (th:if의 편의 버전)
    th:errorclass : th:field에서 지정한 필드에 오류가 있으면 class 정보를 추가함
    <div class="form-group mb-3">
         <label for="passwd">Password:</label>
         <input type="password" id="passwd" th:field="*{passwd}" th:errorclass="field-error" class="form-control">
         <div class="field-error" th:errors="*{passwd}"> 비밀번호 입력 오류 </div>
    </div>

     

    애노테이션 사용

    • 검증기 직접 생성방법
    public class BindigResultValidate implements Validator {
        @Override
        public boolean supports(Class<?> clazz) {
            return Member.class.isAssignableFrom(clazz);
        }
    
        @Override
        public void validate(Object target, Errors errors) {
    
            Member member = (Member) target;
            BindingResult bindingResult = (BindingResult) errors;
    
            //로그인ID
            if ( !StringUtils.hasText(member.getLoginId())){
                bindingResult.addError(new FieldError("member", "loginId","로그인 아이디는 필수입력입니다."));
            }
    
            //이름
            if (!StringUtils.hasText(member.getName())){
                bindingResult.addError(new FieldError("member", "name", "이름은 필수 입력값입니다."));
            }
    
            //비밀번호
            if ( member.getPasswd() != null && member.getPasswd().length() >= 8 ){
                if (member.getPasswd().matches("[a-zA-Z]+")){
                    bindingResult.addError(new FieldError("member","passwd", "비밀번호는 숫자와 특수문자를 포함해야합니다."));
                }else if (member.getPasswd().matches("[0-9]+")) {
                    bindingResult.addError(new FieldError("member", "passwd", "비밀번호는 문자와 특수문자를 포함해야합니다"));
                }else if (member.getPasswd().matches("[a-zA-Z0-9]+")){
                    bindingResult.addError(new FieldError("member","passwd", "비밀번호는 특수문자를 포함해야합니다 "));
                }
            }else{
                bindingResult.addError(new FieldError("member","passwd", "비밀번호는 문자,숫자,특수문자를 포함하여 8자이상이어야합니다."));
            }
    
        }
    }
    @PostMapping("/form")
        public String registryMember(@ModelAttribute Member member, BindingResult bindingResult, Model model){
            
            //생성자 주입으로 넣기
            bindingResultValidate.validate(member,bindingResult);
    
            if (bindingResult.hasErrors()){
                return "member/member-form";
            }
    
            memberRepository.save(member);
            return "redirect:/members/login";
        }
    • @Validated로 적용
      • bindingResultValidate 미리 등록
        • @InitBinder -> WebDataBinder로 validate 등록
      • @Validated 를 @ModelAttribute앞에 추가
    @InitBinder
    private void init(WebDataBinder webDataBinder){    
        webDataBinder.addValidators(bindingResultValidate);
    }
    
    @PostMapping("/form")
        public String registryMember(@Validated @ModelAttribute Member member, BindingResult bindingResult, Model model){
    
            if (bindingResult.hasErrors()){
                return "member/member-form";
            }
    
            memberRepository.save(member);
            return "redirect:/members/login";
        }
Designed by Tistory.