본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


SPRING BOOT

Spring boot 공부 2 - validation 과 custom validation 만들기

반응형

스프링이 요청데이터에 대한 검증을 해줄 수 있다 . 

 

컨트롤러로 들어오는 요청데이터를 파라미터로 지정된 오브젝트에 어노테이션을 활용해 검증할 수 있다 .

 

validation 을 사용하기 위해선  maven 혹은 gradle에 dependency를 추가해줘야한다 .

 

maven dependency

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

//메이븐 

 gradle dependency

 

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 

 

 

validtaion annotation을 활용하지 않은 검증방식 

 

위와 같이 컨트롤러에서 들어오는 객체의 필드를 일일이 검증해야 했지만

 

어노테이션을 사용하면 아래와 같이 사용가능하다.

 

 

 만약 검증해야할 데이터가 있다면  위처럼 해당 파라미터에 @Valid를 붙혀줘야한다. 

 

파라미터로 받을 오브젝트의  클래스에 위와 같이 어노테이션을 붙혀주면된다. 

 

스프링에서 만들어 놓은 검증 어노테이션의 종류와 사용법은 아래에서 찾아 보면된다. 

 

https://www.baeldung.com/javax-validation (validation annotation 종류와 사용법)

 

중요한 점은  위 처럼 User 필드가 List 형식의 cars 필드를 갖고 있을 경우 해당 필드에

 

@Valid를 달아줘야 해당 클래스로 들어가 검증을 한다.

 

 

만약 @Valid가 없다면 Car 클래스에 대한 검증은 일어나지 않는다. 

 

 

custom annotation 

 

필요에 맞게 validation annotaion을 만들어 사용할 수도 있다  

custom한 annotation을 만들기 위해선 일단 본인이 생각하는 어노테이션을 만들면 된다.

 

 

닉네임을 숫자로만 사용할 수 있도록 검증하는 어노테이션을 만들어 보려한다 

(이미 @Pattern으로 정규식 검증이 가능하지만 예제로 만들어 보려한다.)

 

 

 

그림 1, Dto 클래스의 필드에 직접 만든 @Nickname을 붙혀 검증하려한다.

 

Nickname annotation 코드

 

위 어노테이션만으로 사용할 수 있는 것은 아니다  위의 어노테이션은 껍데기이고 실제 검증을 위한 Validator를 구현해 야 한다.  위의 어노테이션에 Validator를 꽂아 넣는다고 생각하면  될 것 같다. @Constraint가 연결시켜 주는 역할을 해준다. 

 

실제 검증하는 역할을 할  validator는 아래와 같다 .

 

validator를 만들기 위해서는 ConstraintValidator 인터페이스를 구현해야한다 제네릭 타입으로  첫번째는 해당 validator를 작동시킬 annotation , 두번째로는 검증할 값의 타입이 들어가면 된다 .  

 

ConstraintValidator 인터페이스는 initialize 와 isValid 두가지 메서드를 구현하도록 되어 있다. 

 

initialize은 해당 어노테이션의 메타데이터들을 가져와  validator 클래스 필드에 초기화 시키는 역할을 한다.  

 

나는 정규식을 사용하기 위해  String 타입으로 pattern 필드를 두었다 .   @Nickname(pattern="(이 부분)") 의 값이 

필드에 저장될 것이다 .

 

isValid 메서드는   실제로 검증을 하는 로직이 들어갈 메서드이다 boolean 타입을 리턴하며 false 일 경우  검증 실패 이고 true일 경우 검증 성공이다 .  파라미터로 들어오는 value는 실제 검증할 값이 들어오며 두번째 파라미터인 ConstraintValidatorContext는 제약조건에 대한 정보를 가져오가나  재정의 하거나하는 메서드들이 있다.

 

작동을 시켜보쟙.

 

 

 

talend API를 통해 테스트를 해봤다 . 닉네임은 현재 123 으로 그림 1 에 지정한 정규식에 어긋나지 않기 때문에 

아래와 같이 잘 처리되어 응답 되었다 .

 

 

 

닉네임을 정규식에 어긋나게  문자("ㅁㄴㅇ")으로 해보자

 

 

 

그림 3

요청이 실패했다고 응답이 왔고 , 응답 body에는 annotation에 정의했던 message와 오류가 난 필드가 전달되었다 . 

저절로 위처럼 되는 것이 아니라  ResponseEntity를 통해 응답데이터를 만들어낸 결과이다 .

 

 

Controller

 

BindingResult안에는 바인딩을 하며 생긴 에러와 바인딩하는 model의 정보가 담겨 있다 . 

 

위에서는 에러가 있을시에 Http상태코드를 400 잘못된 요청으로 지정하고  bindingResult에서 에러를 꺼내 해당 에러의 메시지와 에러가난 필드의 이름을 가져와 StringBuffer에 담고 응답 바디에 담아줬다. 위의 그림 3과 같은 의미이다. 

반응형