[Code-State] SECTION-3 Spring DTO 유효성 검증

유형찬·2022년 10월 24일
0

Code States

목록 보기
15/21

Spring 에서 DTO 유효성 검사

1. DTO 유효성 검사

데이터베이스에 올바른 데이터만 저장하기 위해서는 DTO에 유효성 검사를 해야한다.

물론 프론트에서도 유효성 검사를 해야하나 , API 서버를 통해서 데이터를 받는 경우에는 프론트에서 유효성 검사를 할 수 없다.

따라서 백엔드에서 유효성 검사를 해야한다.

Spring 에서는 DTO 에 대한 유효성 검사를 어노테이션을 통해 쉽게 할 수 있다.

@Data
public class UserDto {
    @NotBlank
    private String name;
    @NotBlank
    private String email;
    @NotBlank
    private String password;
}

위와 같이 DTO에 유효성 검사를 할 어노테이션을 추가하면 된다.

스프링에서 제공하는 유효성 검사 어노테이션은 다음과 같다.

어노테이션설명
@Nullnull 인지 검사
@NotNullnull 이 아닌지 검사
@AssertTruetrue 인지 검사
@AssertFalsefalse 인지 검사
@Min(value)최소값 검사
@Max(value)최대값 검사
@DecimalMin(value)최소값 검사
@DecimalMax(value)최대값 검사
@Size(max, min)최소, 최대값 검사
@Digits (integer, fraction)정수, 소수 자릿수 검사
@Past과거 날짜인지 검사
@Future미래 날짜인지 검사
@Pattern(value)정규식 검사

제공하는 어노테이션 외에 복잡한 문자열 같은 경우에는 정규식을 많이 이용하거나
커스텀 어노테이션을 사용하기도 한다.

1.1 커스텀 어노테이션

커스텀 어노테이션을 사용하면 복잡한 유효성 검사를 쉽게 할 수 있다.

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {EmailValidator.class})
public @interface Email {
    String message() default "올바른 이메일 형식이 아닙니다.";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

위와 같이 어노테이션을 만들고, 어노테이션에 대한 검사를 할 클래스를 만들어준다.

public class EmailValidator implements ConstraintValidator<Email, String> {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        return value.matches("^[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$");
    }
}

위와 같이 어노테이션을 만들어 사용할 수 있다.

1.2 유효성 검사 실패시 에러 메시지

유효성 검사를 통과하지 못하면 에러 메시지를 보여줘야 한다.

@Data
public class UserDto {
    @NotBlank
    private String name;
    @NotBlank
    @Email
    private String email;
    @NotBlank
    private String password;
}

위와 같이 DTO에 유효성 검사를 할 어노테이션을 추가하고, 컨트롤러에서 유효성 검사를 한다.

@PostMapping("/users")
public ResponseEntity<UserDto> createUser(@RequestBody @Valid UserDto userDto) {
    return ResponseEntity.ok(userDto);
}

위와 같이 유효성 검사를 하고, 에러가 발생하면 MethodArgumentNotValidException이 발생한다.

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setMessage("잘못된 요청입니다.");
    errorResponse.setCode("E001");
    errorResponse.setStatus(400);

    List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
    List<ErrorResponse.Error> errors = fieldErrors.stream()
            .map(error -> new ErrorResponse.Error(error.getField(), error.getDefaultMessage()))
            .collect(Collectors.toList());
    errorResponse.setErrors(errors);

    return ResponseEntity.badRequest().body(errorResponse);
}

위와 같이 MethodArgumentNotValidException을 처리해주면 에러 메시지를 보여줄 수 있다.

2. @Valid

@Valid 어노테이션을 사용하면 객체에 있는 유효성 검사를 할 수 있다.

@PostMapping("/users")
public ResponseEntity<UserDto> createUser(@RequestBody @Valid UserDto userDto) {
    return ResponseEntity.ok(userDto);
}

위와 같이 @Valid 어노테이션을 사용하면 객체에 있는 유효성 검사를 할 수 있다.

2.1 @Validated

@Validated 어노테이션을 사용하면 객체에 있는 유효성 검사를 할 수 있다.

@PostMapping("/users")
public ResponseEntity<UserDto> createUser(@RequestBody @Validated UserDto userDto) {
    return ResponseEntity.ok(userDto);
}

위와 같이 @Validated 어노테이션을 사용하면 객체에 있는 유효성 검사를 할 수 있다.

2.2 @Valid와 @Validated의 차이

@Valid는 JSR-303의 기본 어노테이션을 사용하고, @Validated는 Spring의 어노테이션을 사용한다.

@Validated 는 @Valid의 내용을 포함하며 그룹핑을 지원한다.

profile
rocoli에요

0개의 댓글