진짜 개발자
본문 바로가기

FrameWork/Spring Boot

Spring Boot - Custom Validator를 생성해야하는 경우와 생성방법(Collection 검증)

728x90
spring boot custom valid

Spring Boot Custom Validator를 만들어 요청 값 검증하기 (Collection 검증시 발생하는 에러해결)

Rest API 개발시, 사용자의 요청값을 검증해야 하는 경우가 발생합니다.

 

이미 Spring이 아닌 javax 에서 제공하는 어노테이션들이 있으며, Spring에서는 이 어노테이션이 부여된 값들을 검증하도록 구현할수 있습니다.

 

 

하지만, 기본으로 제공하는 어노테이션들로 우리의 복잡한 도메인의 모든 상황들을 검증 할 수는 없습니다. 따라서, 특정상황에서는 직접 Validator를 생성해야 합니다. 이번 포스팅에서는 Validator를 생성해야하는 경우를 알아보고, Validator를 직정 생성하도록 하겠습니다.

 

 

 

 

1. Custom Validator가 필요한 상황(List 검증)

사용자의 요청이 종종 List 인 경우가 있는데요, 이때, List에 검증 어노테이션을 부여하는 경우, 제대로된 검증이 이루어지지 않습니다. 우선 검증할 대상을 더 자세히 설명드리겠습니다.

 

검증 대상 객체

우리가 검증할 객체입니다. num 필드의 값이 반드시 10보다 같거나 커야하는 제한입니다.

 

사용자의 요청을 검증하는 Controller입니다. Event를 검증하기 위해, @Valid 어노테이션을 부여했습니다. 앞서 설정했듯, event의 num필드의 값은 반드시 10보다 같거나 커야합니다. 검증에 성공한다면, console에 num이 출력됩니다.

(*Tip : 사용자의 요청을 검증하는 로직은 당연히 Controller 계층에서 이루어져야 합니다. 사용자의 요청을 처음으로 맞이하는 계층이기 때문인데요, 이 계층에서 검증을 하지 않고 다른 계층에서 필요할때 검증을 하게 되는경우, 검증 코드가 분산되기 때문에 유지보수가 어렵고, 중복된 코드가 발생하기 때문입니다.)

 

PostMan을 이용해 요청을 합니다.

 

우리가 원하는 대로 검증이 잘 이루어짐을 볼 수 있습니다.

 

 

Collection 검증

java에서 기본으로 제공하는 Valid 어노테이션들은, 하나의 객체를 검증합니다. 때문에 요청에서 검증할 대상이 Collection인 경우 Spring은 Collection 객체 자체를 검증하려고 합니다. 직접 예제를 보며 설명드리겠습니다.

 

 

이번엔 사용자의 요청에 List가 담겨있는 경우의 테스트입니다. 마찬가지로 검증 결과에 문제가 없다면, 각각의 num을 콘솔에 출력합니다.

 

PostMan을 이용해 List를 본문에 담아 요청을 전송합니다.

 

결과는 ? 이상하게 검증을 모두 통과하고, num이 출력되었습니다.

 

 

왜?!

원인은 바로, Spring에서 @Valid가 부여된 List<>자체를 검증하려고 하기 때문입니다. List는 Java에서 제공되는 자료구조로써, 우리가 직접 Valid관련 어노테이션을 부여할 수 없습니다. 때문에, List안에 담겨있는 Event에 대한 검증이 이루어지지 않았기 때문에 요청이 성공적으로 이루어진 것입니다.

 

 

 

 

2. List 검증을 위한 Custom Validator 생성

문제점 파악

List을 검증하기 위해서는 어떻게 해야 할까요?, 문제점을 다시 생각해봅시다.

 

Spring은 @Valid가 부여된 객체 자체를 검증한다. 하지만, 우리의 목표는 List안에 담긴 객체 하나하나를 검증해야합니다. 따라서, List를 순회하며 하나하나의 객체를 검증하도록 하면 됩니다.

 

Custom Validator 생성

  1. 우선 Validator를 구현하고, @Component 어노테이션을 이용해 Bean으로 등록합니다.
  1. 검증을 위해 SpringValidatorAdapter 를 주입받습니다.
  1. supports() 메소드에서는, 검증 대상이 List인지를 확인합니다.
  1. validate() 메소드에서는 target을 Collection으로 캐스팅한뒤 담겨있는 객체를 순회하며, validator를 이용해 검증을 합니다.

 

 

Controller에서 Custom Validator 사용**

  1. 앞서 생성한 CustomrValidator 주입받습니다.
  2. customVliadator를 이용하여, eventList를 검증하도록 요청합니다.
  3. 검증 결과는 Errors 객체에 담겨있습니다.
  4. errors의 모든 검증 결과를 출력합니다.

 

다시 List를 요청 본문에 담아 요청합니다.

 

9, 8, 7 값에 대한 검증이 성공적으로 이루어졌습니다.