[스프링부트] Spring Boot의 Validation : @Valid 어노테이션으로 유효성 검증하기

minji·2022년 9월 21일
2
post-thumbnail
post-custom-banner

스프링부트가 제공하는 어노테이션을 사용하면 쉽게 데이터에 대한 유효성 검증을 할 수 있는데, 그 방법을 기록해두려고 한다.

유효성 검증이란?

데이터 필드가 정의한 스펙에 대해 올바른 값인지를 검증하는 것이다.
예컨대 varchar(10) 으로 설정된 컬럼의 값이 10자를 넘어간다던지,
not null 로 설정된 컬럼의 값에 null 이 들어가는 경우에는 유효성 검증에 실패했다고 말한다.


1️⃣ 라이브러리 추가

각자의 환경에 맞게 라이브러리를 추가한다.

  • maven
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>
  • gradle
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-validation'
}

2️⃣ 제약조건 설정

대표적으로 자주 사용되는 제약조건 어노테이션의 종류는 다음과 같다.
(출처 : https://reflectoring.io/bean-validation-with-spring-boot/)

  • @NotNull : 해당 필드에 null값을 불허한다.

  • @NotEmpty : 해당 필드에 null, ""을 불허한다.

  • @NotBlank : 해당 필드에 null, "", " " 을 불허한다. 즉 최소 1글자

  • @Min : 해당 필드의 최소값을 벗어나는지 검증한다.

  • @Max : 해당 필드의 최대값을 벗어나는지 검증한다.

  • @Pattern : 해당 필드가 특정 형태를 가지도록 검증한다. (정규표현식으로 표현함)

  • @Email : 해당 필드가 이메일 형식을 가지도록 검증한다.

  • @Size : 문자열의 최소, 최대 크기를 검증한다.
    @Size(min=10, max=100) 과 같이 사용할 수 있으며, 기본값은 min=0, max=정수형의 최대값 이다.

이제 원하는 클래스에 각 컬럼의 속성에 맞게 어노테이션들을 지정해준다.
message에는 해당 제약조건이 위배되었을 때 알릴 메세지를 지정해주면 된다.


3️⃣ @Valid 어노테이션 지정

검증할 대상의 앞에 @RequestBody 와 함께 @Valid 어노테이션을 붙여준다. 해당 인풋에 대해 유효성을 검증하겠다고 hibernate에게 알려주는 것이다.

참고로 꼭 특정 객체를 인자로 받지 않는 단일 파라미터에 대해서도 가능하다.

@GetMapping("/validationExample")
ResponseEntity<String> validationExample( @RequestParam("param") @Min(5) int param) { 
    return ,,, ;
}

다음과 같이 원하는 제약조건의 어노테이션을 붙여주면 된다.


4️⃣ 예외 처리

이제 지정한 제약조건에 위배되는 데이터가 들어오면 어떻게 처리될까?

스프링부트는 유효성 검증이 실패했을 때 MethodArgumentNotValidException 을 반환한다.
즉, 이 예외에 대해 처리를 해주면 된다.(자세한 예외처리 클래스 설정은 다음 글 참고)

  • @ExceptionHandler(MethodArgumentNotValidException.class) : MethodArgumentNotValidException 이 발생하면 아래의 메서드를 실행하도록 한다.

  • @ResponseStatus(HttpStatus.BAD_REQUEST) : 클라이언트가 잘못된 인풋을 전달한 경우에 해당하므로 상태코드는 400.BAD_REAUEST 로 지정해주었다.

그리고 우리가 위에서 지정한 message 를 가져오기 위해서는 ,
e.getBindingResult().getAllErrors().get(0).getDefaultMessage() 를 응답 결과로 지정한다.

get(0) 이므로 여러 필드에 대해 유효성검증에 실패했어도 첫 필드에 대한 메세지만 출력된다.


5️⃣ 테스트

  • categoryId 의 @NotNull 제약조건을 위배했을 때 (값을 넣지 않음)

  • productName 의 @Size 제약조건을 위배했을 때 (20자 이상을 입력함)

다음과 같이 지정한 메세지와 함께 어느 제약조건이 위배되었는지 알 수 있다.

profile
SW Engineer
post-custom-banner

0개의 댓글