FireDrago

[Spring] Bean Validation 본문

프로그래밍/Spring

[Spring] Bean Validation

화이용 2024. 2. 12. 15:37

이전 포스팅에서 스프링 검증에 대해서 알아보았다. 이번에는 복잡한 검증코드 없이 애너테이션으로 간편하게

검증을 할 수 있는 방법에 대해서 알아보자

 

<Bean Validation>

Bean Validation은 애너테이션으로 쉽게 검증을 처리 할 수 있도록 하는 표준 기술이다. (인터페이스) 

대표적인 구현체로 하이버네이트 Validator 가 있고, 실무에서 가장 많이 사용된다.

하이버네이트Validator 애너테이션  사용법 : 링크

 

Hibernate Validator 8.0.1.Final - Jakarta Bean Validation Reference Implementation: Reference Guide

Validating data is a common task that occurs throughout all application layers, from the presentation to the persistence layer. Often the same validation logic is implemented in each layer which is time consuming and error-prone. To avoid duplication of th

docs.jboss.org

 

1. 스프링에서 사용하기 

스프링 부트에서 Bean Validation을 사용하려면 먼저 라이브러리를 등록해줘야한다.

 

라이브러리가 등록되면 스프링은 LocalValidationFactoryBean을 글로벌 Validator로 등록한다. 

LocalValidationFactoryBean은 애너테이션 (@NotNull, @NotEmpty,...)등을 인식하고 검증을 수행한다.

검증을 수행하여 오류가 있는 경우, FieldError, ObjectError 객체를 생성하고, BindingResult 객체에 전달한다.

@Validated 를 사용한 메서드의 경우에만 검증이 수행된다. @Validated는 ComponentScan 에 의해 인식된다.

도메인에 BeanValidation 애너테이션 적용
컨트롤러에서 검증 호출

 

 

2. 검증 순서

 

BeanValidation은 @ModelAttribute 객체의 필드에 타입변환이 된 후에 실행된다는 점을 기억하자

예를들어 int 필드에 문자열 값을 입력했다면 BeanValidation은 검증을 실행하지 않는다.

타입변환에서 에러가 발생했기 때문에 스프링이 typeMismatch 에러코드로 FieldError 를 생성한다.

 

BeanValidation의 오류코드는 정해진 순서에 따라 생성되며,

오류코드, 애너테이션 message 속성, 라이브러리 기본 메시지

순서로 오류메시지를 찾는다.

오류코드 생성 순서 및 message 속성

 

3. 검증조건 분리하기

상품입력 때는 수량의 제한이 9999개이지만, 상품 수정때는 수량의 제한이 없도록 하고싶을때 어떻게 해야할까?

상황에따라 검증로직이 달라지는 경우, 어떻게 해야할까?

 

1. groups 속성 사용

1. groups 속성에서 사용하기 위한 인터페이스 생성
2. groups 속성으로 상황에 따라 적용될 검증 애너테이션 지정
3. @Validated 에 상황에 맞는 인터페이스 설정

 BeanValidator는 상황에 따라 검증로직이 다르게 적용될 수 있도록 groups 속성을 지원한다.

1. 먼저 groups 속성에 사용하기 위한 인터페이스를 생성한다. 2가지 상황이 있다면 인터페이스는 2개가 필요하다.

2. 도메인 객체에 상황에 따라 적용할 검증 애너테이션을 groups 속성을 사용하여 지정한다.

3. 컨트롤러에서 검증을 실시할때는 @Validated ( 인터페이스.class) 로 상황을 설정한다.

 

2. 객체의 분리

실무에서는 groups 보다 상황에따라 객체를 분리하는 경우가 더 많다. 

예를들어 회원가입시에는 회원객체의 정보뿐만 아니라 약관동의 여부 등 부가적인 정보가 함께 전송된다.

또 회원수정시에는 주민등록번호를 가져올 필요가 없다. 상황에 따른 객체를 생성해서 사용하는 이유이다.

이 경우, 컨트롤러에서 도메인 객체로 변환해주는 수고가 필요하다. 코드로 살펴보자.

상품 등록과 상품 수정 담당 객체를 각각 생성했다.
검증에 통과한 경우 Item 도메인 객체로 변환과정이 필요

상품 등록과 상품 수정을 담당하는 객체를 분리했다. 그리고 @ModelAttribute 에서 ("item") 빼먹지 않도록 주의하자

설정을 빼먹으면 자동으로 객체명(앞글자 소문자)로 Model에 전달된다.

마지막 코드에서  검증이 성공한 경우, Item 도메인 객체로 변환해주는 추가적인 과정이 필요하다.

 

참고로 BeanValidation 을 사용하여 ObjectError를 검증할때는 자바 코드로 에러를 검증하도록 하자 

@ScriptAssert() 는 최신버전의 스프링부트에서 더이상 지원하지 않는다. 실무에서도 잘 사용되지 않는다고 한다.

 

 

4. HTTP MessageConverter 적용하기 (@ResponseBody)

@Valid , @Validated 는 HttpMessageConverter ( @RequestBody )에도 적용할 수 있다

@ModelAttribute 는 HTTP 요청 파라미터(URL 쿼리 스트링, POST Form)를 다룰 때 사용한다.
@RequestBody 는 HTTP Body 데이터를 객체로 변환할 때 사용한다.

주로 API JSON 요청을 다룰때 사용한다

 

@ModelAttribute 검증을 실행할때는 필드단위로 실행되며, 하나의 필드에 문제가 있어도 다른 필드의 검증은 실행된다.

반면에 @RequestBody는 하나의 덩어리로 검증이 실행되기 때문에 여러 필드 중 하나만 문제가 있어도 예외가 발생한다. 이때는 예외처리를 해줘야 한다.

에러를 출력

'프로그래밍 > Spring' 카테고리의 다른 글

[Spring] 서블릿 필터와 스프링 인터셉터  (0) 2024.02.15
[Spring] 로그인 쿠키와 세션  (0) 2024.02.14
[Spring] 검증처리  (0) 2024.02.09
[Spring] HttpMessageConverter  (0) 2024.02.01
[Spring] Spring 기본기능  (0) 2024.01.30