Spring & Spring boot

[Spring Boot] Validation - 1. @Valid 어노테이션 사용방법

jh4dev 2024. 8. 14. 16:06
<목차>

1. 유효성 검사
2. @Valid 어노테이션 테스트
3. 유효성 검사 어노테이션

 

[유효성 검사]

애플리케이션의 비즈니스 로직이 올바르게 동작하기 위해, 데이터를 사전 검증하는 유효성 검사 작업이 필요하다.

유효성 검사란, 각 계층에서 들어오는 데이터에 대해, 의도한 형태대로 값이 들어오는지 체크하는 과정을 말한다.

 

계층별로 진행하는 유효성 검사의 경우, 검증 로직이 각 계층 클래스 별로 분산되어 있어 관리하기 어렵다는 문제가 있다.

또한 유효성 검사 로직 자체가 중복되는 경우가 많아, 불필요한 중복 소스가 발생하며, 검증해야하는 값이 많다면 코드 또한 몇 배로 길어지게 된다.

 

이런 문제를 해결하기 위해, JAVA 에서는 Bean Validation 이라는 프레임워크를 제공하고 있으며, 스프링 부트에서는 Bean Validation 의 구현체인 Hibernate Validator 를 유효성 검사의 표준으로 채택하여 사용하고 있다.

 

Hibernate Validator 는, 도메인 모델에서 어노테이션을 통해 필드값을 검증할 수 있도록 기능을 제공한다.

 

스프링 부트에서 유효성 검사는,

각 계층으로 데이터가 넘어오는 시점에, 해당 데이터에 대한 검사를 실시한다.

 

유효성 검사


[@Valid 어노테이션]

유효성 검사를 위해 DTO 에 어노테이션을 통해 체크할 내용을 설정하고, 클라이언트로부터 넘어온 Request 에 대해 Controller 에서 유효성 검사를 실행하는지 확인해보자.

 

1. DTO 생성

<ValidRequestDto> DTO

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @ToString
    @Builder
    public class ValidRequestDto {

        @NotBlank
        String name;

        @Email
        String email;

        @Pattern(regexp = "01(?:0|1|[6~9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$")
        String phoneNumber;

        @Min(value=20) @Max(value=40)
        int age;

        @Size(min = 0, max = 40)
        String description;

        @Positive
        int count;

        @AssertTrue
        boolean booleanCheck;

    }

 

2. 컨트롤러 생성

<ValidationController> Controller

    @RestController
    @RequestMapping("/validation")
    @Slf4j
    public class ValidationController {

        @PostMapping("/valid")
        public ResponseEntity<ValidRequestDto> checkValidationByValidAnno(
        @Valid @RequestBody ValidRequestDto validRequestDto) {

            log.info(validRequestDto.toString());

            return ResponseEntity.status(HttpStatus.OK).body(validRequestDto);
        }
    }
  • 컨트롤러의 파라미터 부분을 보면, @Valid 어노테이션이 적용한 것을 확인할 수 있다.

 

3. 애플리케이션 실행 및 스웨거 접속

스웨거가 설정되어있지 않다면, Postman 과 같은 소프트웨어를 사용해도 무관하다.
** Swagger 설정 방법 **
 

[Springboot] springdoc 을 사용하여 Swagger 설정하기 - 1

1. Swagger ?2. springdoc - springfox3. Setting [Swagger ?]API를 개발함에 있어, 명세 관리는 필수이다.해당 API가 어떤 로직을 수행하는지 설명하고, 이 로직을 수행하기 위해 어떤 값을 필요로 하며, 이 로직

jh4dev.tistory.com

 

 

[Springboot] springdoc 을 사용하여 Swagger 설정하기 - 2

1. API 명세2. Schemas 명세 Springdoc OpenAPI 는 다양한 어노테이션을 활용해 API 문서를 쉽게 생성하고 관리할 수 있도록 해준다. 다음과 같은 Get API 기준으로 각종 어노테이션을 적용해보자. @GetMapping

jh4dev.tistory.com

 

swagger API

4. 테스트

  • 정상 케이스
  • {
      "name": "테스트",
      "email": "test@test.com",
      "phoneNumber": "010-4321-1234",
      "age": 40,
      "description": "설명",
      "count": 1,
      "booleanCheck": true
    }
  • 결과 (Status 200)


  • 실패 케이스
  • age 의 최소값을 20으로 설정하였기에, 10으로 호출해보자.
    {
      "name": "테스트",
      "email": "test@test.com",
      "phoneNumber": "010-4321-1234",
      "age": 10, // age 의 최소값을 20으로 설정하였기에, 10으로 호출
      "description": "설명",
      "count": 1,
      "booleanCheck": true
    }
  • 결과 (Status 400)
    별다른 에러 처리를 하지 않았기에 Http Status Code = 400 으로 처리된 것을 확인할 수 있다.

  • 로그도 살펴보자.
    아래와 같이, 해당 필드에 대한 메시지까지 자동으로 생성되는 것을 확인할 수 있다.

    [2024-08-14 15:54:20.416] [WARN ] [http-nio-8080-exec-3] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<cohttp://m.springboot.valid.data.dto.ValidRequestDto> cohttp://m.springboot.valid.controller.ValidationController.checkValidationByValidAnno(com.springboot.valid.data.dto.ValidRequestDto): [Field error in object 'validRequestDto' on field 'age': rejected value [10]; codes [Min.validRequestDto.age,Min.age,Min.int,Min]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [validRequestDto.age,age]; arguments []; default message [age],20]; default message [20 이상이어야 합니다]] ]


[유효성 검사 어노테이션]

간단하게 유효성 검사가 동작하는 부분에 대해 알아보았으며, 도메인 모델에 적용할 수 있는 유효성 검사 어노테이션에 대해 정리해본다.
어노테이션
설명 적용 가능 타입
@NotNull 해당 필드가 null이면 안되며 필수 입력 값 모든 참조 타입 (객체)
@NotEmpty 문자열이나 컬렉션이 비어 있으면 안된다.. (null과 빈 값을 모두 허용하지 않음) String, Collection, Map, Array
@NotBlank 문자열이 공백을 포함한 빈 문자열이면 안된다. (공백만 있는 경우도 허용하지 않음) String
@Size 문자열, 컬렉션, 배열 등의 크기나 길이를 제한한다. String, Collection, Map, Array
@Min 숫자의 최소값을 제한한다. int, long, short, byte, BigDecimal, BigInteger
@Max 숫자의 최대값을 제한한다. int, long, short, byte, BigDecimal, BigInteger
@Pattern 정규 표현식으로 문자열 패턴을 제한한다. String
@Email 이메일 형식인지 검증한다. String
@Digits 숫자의 정수부와 소수부의 자릿수를 제한한다. String, BigDecimal, BigInteger
@Positive 양수(0보다 큰 값)인지 검증한다. int, long, short, byte, BigDecimal, BigInteger
@PositiveOrZero 양수 또는 0인지 검증한다. int, long, short, byte, BigDecimal, BigInteger
@Negative 음수(0보다 작은 값)인지 검증한다. int, long, short, byte, BigDecimal, BigInteger
@NegativeOrZero 음수 또는 0인지 검증한다. int, long, short, byte, BigDecimal, BigInteger
@Future 해당 날짜가 미래인지 검증한다. Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime
@Past 해당 날짜가 과거인지 검증한다. Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime
@FutureOrPresent 해당 날짜가 미래이거나 현재인지 검증한다. Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime
@PastOrPresent 해당 날짜가 과거이거나 현재인지 검증한다. Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime
@AssertTrue 필드 값이 true인지 검증한다. boolean, Boolean
@AssertFalse 필드 값이 false인지 검증한다. boolean, Boolean
@CreditCardNumber 신용카드 번호 형식이 유효한지 검증한다. String
@Length 문자열의 길이를 제한한다. @Size와 유사하지만, 주로 Hibernate Validator에서 사용된다. String
@Range 숫자의 범위를 제한한다. @Min과 @Max의 대체로 사용된다. int, long, short, byte, BigDecimal, BigInteger
@URL 유효한 URL 형식인지 검증한다. String
@Valid 해당 필드가 포함된 객체가 유효한지 검증한다. 객체 필드 내의 어노테이션을 적용할 때 사용한다. 모든 참조 타입 (객체)
@Null 해당 필드가 null이어야 함을 검증한다. 모든 참조 타입 (객체)
@DecimalMin BigDecimal이나 BigInteger 타입의 최소값을 설정한다. @Min보다 정밀도를 지원한다. BigDecimal, BigInteger, String, byte, short, int, long
@DecimalMax BigDecimal이나 BigInteger 타입의 최대값을 설정한다. @Max보다 정밀도를 지원한다. BigDecimal, BigInteger, String, byte, short, int, long
@PastOrPresent 날짜가 과거 또는 현재인지 검증한다. Date, Calendar, LocalDate, LocalDateTime, ZonedDateTime

 

JAVA 에서 제공하는 @Valid 어노테이션 사용 방법에 대해 알아보았으며,

다음 포스팅에서는 스프링에서 지원하는 @Validated 어노테이션에 대해 알아보자.