[Spring Boot] @Validation Exception 처리하기

2021. 6. 2. 11:37Spring

로그인, 회원가입 @Validation exception을 객체로 따로 빼기

  1. DTO에서 @Validation 설정하기

    UserLoginRequestDto.java

    • public class UserLoginRequestDto {
          @NotBlank(message = "아이디는 필수 입력입니다.")
          @Pattern(regexp = "^[a-zA-Z0-9]{3,20}$", message = "3~20자리의 숫자 또는 문자만 가능합니다.")
          private String username;
      
          @NotBlank(message = "비밀번호는 필수 입력입니다.")
          @Pattern(regexp = "^.*(?=^.{4,15}$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$", message = "비밀번호는 4~15자리의 숫자,문자,특수문자로 이루어져야합니다.")
          private String password;
      }    

UserSignUpRequestDto.java

  • public class UserSignupRequestDto {
        @NotBlank(message = "이름은 필수 입력입니다.")
        @Pattern(regexp = "[a-zA-Z0-9]*",message = "username은 숫자 또는 문자만 가능합니다.")
        private String username;
    
        @NotBlank(message = "비밀번호는 필수 입력입니다.")
        @Pattern(regexp = "^.*(?=^.{4,15}$)(?=.*\\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$", message = "비밀번호는 4~15자리의 숫자,문자,특수문자로 이루어져야합니다.")
        private String password;
    
        @NotBlank(message = "이메일은 필수 입력입니다.")
        @Email(message = "email 형식을 지켜주세요.")
        private String email;
    
        @NotBlank(message = "비밀번호 확인은 필수입니다.")
        private String pwcheck;
    
    }
    
    
 ```
  1. @Vaild 유효성 체크에 통과되지 못하면 MethodArgumentNotVaildException이 발생한다.

    @ExceptionHandler(MethodArgumentNotValidException.class)
        public ResponseEntity<ValidMessageResponse> methodValidException(MethodArgumentNotValidException e, HttpServletRequest request) {
            log.warn("MethodArgumentNotValidException 발생!! url:{}, trace:{}",request.getRequestURI(), e.getStackTrace());
            ValidMessageResponse errorResponse = makeErrorResponse(e.getBindingResult());
            return new ResponseEntity<ValidMessageResponse>(errorResponse, HttpStatus.BAD_REQUEST);
        }
  2. Error Code를 enum으로 만들기

    public enum  ErrorCode {
        NOT_NULL("ERROR_CODE_NOT_NULL", "필수값이 누락되었습니다."),
        MIN_VALUE("ERROR_CODE_MIN_VALUE", "최소값보다 커야 합니다."),
        PATTERN("ERROR_CODE_PATTERN", "값 형식이 다릅니다."),
        NOT_BLANK("ERROR_CODE_BLANK","필수값이 누락되었습니다."),
        EMAIL("ERROR_CODE_EMAIL", "이메일 형식이 아닙니다.");
    
        @Getter
        private String code;
    
        @Getter
        private String description;
    
        ErrorCode(String code, String description) {
            this.code = code;
            this.description = description;
        }
    }
  3. 상황에 맞는 에러를 switch 문으로 찾아서 에러 메세지 만들어서 출력하기

    private ValidMessageResponse makeErrorResponse(BindingResult bindingResult) {
            String code = "";
            String description = "";
            String detail = "";
    
            //에러가 있다면
            if (bindingResult.hasErrors()) {
                //DTO에 설정한 message값을 가져온다.
                detail = bindingResult.getFieldError().getDefaultMessage();
    
                //DTO에 유효성체크를 걸어놓은 어노테이션명을 가져온다.
                String bindResultCode = bindingResult.getFieldError().getCode();
    
                switch (Objects.requireNonNull(bindResultCode)) {
                    case "NotNull" :
                        code = ErrorCode.NOT_NULL.getCode();
                        description = ErrorCode.NOT_NULL.getDescription();
                        break;
                    case "NotBlank":
                        code = ErrorCode.NOT_BLANK.getCode();
                        description = ErrorCode.NOT_NULL.getDescription();
                        break;
                    case "Pattern":
                        code = ErrorCode.PATTERN.getCode();
                        description = ErrorCode.PATTERN.getDescription();
                        break;
                    case "Email":
                        code = ErrorCode.EMAIL.getCode();
                        description = ErrorCode.EMAIL.getDescription();
                        break;
                }
            }
            return new ValidMessageResponse(code,description,detail);
        }