스프링부트가 제공하는 어노테이션을 사용하면 쉽게 데이터에 대한 유효성 검증을 할 수 있는데, 그 방법을 기록해두려고 한다.
유효성 검증이란?
데이터 필드가 정의한 스펙에 대해 올바른 값인지를 검증하는 것이다.
예컨대varchar(10)
으로 설정된 컬럼의 값이 10자를 넘어간다던지,
not null
로 설정된 컬럼의 값에 null 이 들어가는 경우에는 유효성 검증에 실패했다고 말한다.
각자의 환경에 맞게 라이브러리를 추가한다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-validation'
}
대표적으로 자주 사용되는 제약조건 어노테이션의 종류는 다음과 같다.
(출처 : https://reflectoring.io/bean-validation-with-spring-boot/)
@NotNull
: 해당 필드에 null값을 불허한다.
@NotEmpty
: 해당 필드에 null, ""을 불허한다.
@NotBlank
: 해당 필드에 null, "", " " 을 불허한다. 즉 최소 1글자
@Min
: 해당 필드의 최소값을 벗어나는지 검증한다.
@Max
: 해당 필드의 최대값을 벗어나는지 검증한다.
@Pattern
: 해당 필드가 특정 형태를 가지도록 검증한다. (정규표현식으로 표현함)
@Size
: 문자열의 최소, 최대 크기를 검증한다.
@Size(min=10, max=100) 과 같이 사용할 수 있으며, 기본값은 min=0, max=정수형의 최대값 이다.
이제 원하는 클래스에 각 컬럼의 속성에 맞게 어노테이션들을 지정해준다.
message에는 해당 제약조건이 위배되었을 때 알릴 메세지를 지정해주면 된다.
검증할 대상의 앞에 @RequestBody 와 함께 @Valid 어노테이션을 붙여준다. 해당 인풋에 대해 유효성을 검증하겠다고 hibernate에게 알려주는 것이다.
참고로 꼭 특정 객체를 인자로 받지 않는 단일 파라미터에 대해서도 가능하다.
@GetMapping("/validationExample")
ResponseEntity<String> validationExample( @RequestParam("param") @Min(5) int param) {
return ,,, ;
}
다음과 같이 원하는 제약조건의 어노테이션을 붙여주면 된다.
이제 지정한 제약조건에 위배되는 데이터가 들어오면 어떻게 처리될까?
스프링부트는 유효성 검증이 실패했을 때 MethodArgumentNotValidException
을 반환한다.
즉, 이 예외에 대해 처리를 해주면 된다.(자세한 예외처리 클래스 설정은 다음 글 참고)
@ExceptionHandler(MethodArgumentNotValidException.class)
: MethodArgumentNotValidException 이 발생하면 아래의 메서드를 실행하도록 한다.
@ResponseStatus(HttpStatus.BAD_REQUEST)
: 클라이언트가 잘못된 인풋을 전달한 경우에 해당하므로 상태코드는 400.BAD_REAUEST 로 지정해주었다.
그리고 우리가 위에서 지정한 message 를 가져오기 위해서는 ,
e.getBindingResult().getAllErrors().get(0).getDefaultMessage()
를 응답 결과로 지정한다.
get(0) 이므로 여러 필드에 대해 유효성검증에 실패했어도 첫 필드에 대한 메세지만 출력된다.
categoryId 의 @NotNull 제약조건을 위배했을 때 (값을 넣지 않음)
productName 의 @Size 제약조건을 위배했을 때 (20자 이상을 입력함)
다음과 같이 지정한 메세지와 함께 어느 제약조건이 위배되었는지 알 수 있다.