cso6005 / TIL-Troubleshooting

배움 기록 및 트러블 슈팅 정리
0 stars 0 forks source link

[Spring Boot] 유효성 검사 & 데이터 검증 Vaildation #28

Open cso6005 opened 1 year ago

cso6005 commented 1 year ago

유효성 검사 & 데이터 검증 Vaildation 이란?

Validation 관련 어노테이션

어노테이션 의미
@Size 문자의 길이 조건
@Notnull null 값 불가
@NotEmpty null 값 불가 + “” 값 불가
@NotBlank null 값 불가 + “” 값 불가 + “ “ 값 불가
@Past 과거 날짜
@PastOrPresent 과거 날짜 + 오늘 날짜
@Future 미래 날짜
@FutureOrPresent 미래 날짜 + 오늘 날짜
@Pattern 정규식을 통한 조건
@Max 최대값 조건 설정 (문자열 길이 제한 가능)
@Min 최소값 조건 설정
@AssertTrue/AssertFalse 참/거짓 조건 설정
@Valid 해당 객체의 유효성 검사
cso6005 commented 1 year ago

EX ) 회원 가입 시, 이메일 양식 유효성 검사

package io.csy.hot.model.dto;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@Builder
public class SignUpDTO {

//  @NotBlank // null, 빈 문자열 (스페이스 포함X) 불가
    @NotEmpty(message = "이메일은 빈 값일 수 없습니다.") // null, 빈 문자열, 스페이스만 포함한 문자열 불가
    @Email(message = "이메일 형식을 맞춰주세요.") // 이메일 형식만 가능
    private String accountEmail;

    @NotEmpty(message = "비밀번호는 빈 값일 수 없습니다") // null, 빈 문자열, 스페이스만 포함한 문자열 불가
    @Pattern(regexp="[a-zA-Z1-9]{6,12}", message = "비밀번호는 영어와 숫자로 포함해서 6~12자리 이내로 입력해주세요.")
    private String accountPassword;

    @NotBlank(message = "이름은 빈 값일 수 없습니다")
    @Size(min = 2, max = 8, message = "이름을 2 ~ 8 자 사이로 입력해주세요.")
    private String accountName;

    @NotNull // null 불가능
    private String accountBirth;

    @NotNull
    private String accountAddress;

    @NotNull
    @Pattern(regexp = "^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$", message = "전화번호 양식이 틀렸습니다.")
    private int accountPhoneNumber;

    @NotNull
    private String accountGender;

}
package io.csy.hot.controller;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import io.csy.hot.model.AccountService;
import io.csy.hot.model.dto.AccountDTO;
import io.csy.hot.model.dto.SignUpDTO;

@RestController
@RequestMapping("auth")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class AccountController {

    @Autowired
    private AccountService accountService;

    @PostMapping("/sing-up")
    public void signUp(@Valid @RequestBody SignUpDTO signUp) throws Exception {

        AccountDTO account = accountService.signUp(signUp);

    }

}
cso6005 commented 1 year ago

String detailMessage = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();

cso6005 commented 1 year ago

데이터 유효성 검사 예외 처리

import java.nio.file.AccessDeniedException;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler{

    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    protected ResponseEntity<Object> handleMethodArgumentNotValid(
            MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {

        CommonErrorCode errorCode = CommonErrorCode.METHOD_ARGUMENT_NOT_VALID;
        String detailMessage = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage();

        LOGGER.warn("HandleHttpRequestMethodNotSupportedException:CLIENT REQUEST ERROR:INVALID_METHOD: {}", ex.getMessage());

        return ErrorResponse.toDataVaildErrorResponse(errorCode, detailMessage, request.getDescription(false).substring(4));    }

}
{
    "timestamp": "Fri Feb 03 01:04:30 KST 2023",
    "status": 400,
    "error": "METHOD_ARGUMENT_NOT_VALID",
    "message": "데이터유효성 검사 결과, 규칙에 맞지 않는 데이터입니다. : 전화번호 양식이 맞지 않습니다.",
    "path": "/auth/sing-up"
}