SPRING

[SPRING] Bean Validation

steadyMan 2022. 7. 10. 21:49

직접 조건을 확인하여 validation 처리하는 것이 아닌 필드에  조건을 명시하고 조건에 부합됐을 때 오류 메세지를 생성하고 바인딩까지 처리까지 해준다면 더욱 편리할 것이다. Bean Validation은 애노테이션 기반으로 검증을 매우 편하게 할 수 있도록 한다. 

 

학습의 결과를 정리합니다.

Project Metadata

  • project : Gradle Project
  • Language : Java 11
  • Framework : Spring Boot 2.5.x
  • Template Engine : Thymeleaf

의존성 추가

implementation 'org.springframework.boot:spring-boot-starter-validation'

spring-boot-starter-validation 의존관계를 추가합니다. 

validation 라이브러리

  • jakarta.validation-api - Bean Validaion 인터페이스
  • hibernate-validator - 구현체

스프링의 Bean validator 사용

spring-boot-starter-validation 라이브러리 의존성 추가 시 자동으로 Bean Validator를 스프링 컨테이너에 추가한다. 

LocalValidatorFactoryBean을 글로벌 Validator로 등록한다. 이 Validator는 @Range와 같은 애노테이션을 보고 검증을 

수행하고 검증오류 발생 시 FieldError, ObjectError를 생성해서 BindingResult에 담아준다.

검증 애노테이션 추가 

필요한 검증기능을 제공하는 애노테이션을 객체의 필드위에 선언합니다. 

검증 조건에 부합됐을 때의 메세지를 파라미터로 전달할 수 있는데  

BeanValidation의 메시지 찾는 순서는 

1. 생성된 메시지 코드 순서대로 messageSource에서 메시지 찾기

2. 애노테이션의 message 속성 사용 @NotBlank(message = "공백")

3. 라이브러리가 제공하는 기본 값(default message) 사용

이렇기에 MessageSource를 사용중이라면 코드만 맞춰주면 된다.

@Getter @Setter
public class User {	
    @NotNull // 공백확인 
	private String userId;
	private String password;
	@Range(min = 10, max = 100) // 범위확인
	private int age;
}

다양한 검증 애노테이션 정보는 아래에서 확인가능하다.

Hibernate Validator 6.2.3.Final - Jakarta Bean Validation Reference Implementation: Reference Guide (jboss.org)

 

Hibernate Validator 6.2.3.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

@Validated, @Valid

@PostMapping("/user")
public String userPageValid(@Validated @ModelAttribute User user, BindingResult bindingResult) {
    log.info("bindingResult = {}", bindingResult);
    return "userPage"; 
}

@Validated, @Valid 둘 다 사용 가능하고 검증대상의 객체 앞에 선언해야 Bean Validator의 대상이 된다. 

@Validated는 스프링 전용 검증 애노테이션, @Valid 자바 표준 검증 애노테이션이다.

검증의 결과는 BindingResult에 담긴다. 

필드의 애노테이션에서 전달한 파라미터는 MessageSource사용 시 code에 맞는 메세지로 전달되는데 파라미터의 순서가

애노테이션마다 각각 다르므로 확인하고 사용해야 한다. 

age 필드의 @Range 애노테이션의 파라미터 전달결과

#errors.properties

#{0}은 필드명
Range.user.age=나이는 {2} ~ {1}세 사이여야합니다.

검증 과정 

1. @ModelAttribute는 각각의 필드에 타입 변환(바인딩) 실패하면 typeMismatch 코드로 FieldError 추가

2. 타입 변환에 성공한 필드에 대해 Bean Validation을 적용한다. BeanValidator는 바인딩에 실패한 필드는

BeanValidation을 적용하지 않는다.

@ModelAttribute와 같이 필드 단위로 바인딩하는 것과 다르게 

@RequestBody와 같이 HttpMessageConverter로 데이터를 객체로 한 번 변경해야 하는 경우

타입 오류와 같은 이유로 변경하지 못하면 이후 단계가 아예 진행되지 않기 때문에 주의해야 한다.