본문 바로가기

Development/Spring

[Spring]Validation과 BindingResults을 통한 유효성 검사

 

Validation이란?

Validation은 프로그래밍에 있어서 가장 필요한 부분으로 특히 java에서는 null 값에 대해서는 Null Pointer Exception이 발생하므로 유효성을 사전에 미리 검사하는 것이 Validation이다.

 

Validation의 주의사항

  • 검증해야 할 값이 많아질 경우 코드가 길어진다.
  • 구현의 따라서 달라질 수 있지만 서비스 로직과 분리가 필요할 수도 있다.
  • 흩어져 있는 경우 어디에서 검증을 하는지 알기가 어려우며, 재사용의 한계가 있다.
  • 검증 로직이 변경되는 경우 참조하는 클래스에서 로직이 변경이 필요한 경우도 있다.

 

유효성 검사에 사용되는 어노테이션 목록

@Null  // null만 혀용합니다.
@NotNull  // null을 허용하지 않습니다. "", " "는 허용합니다.
@NotEmpty  // null, ""을 허용하지 않습니다. " "는 허용합니다.
@NotBlank  // null, "", " " 모두 허용하지 않습니다.

@Email  // 이메일 형식을 검사합니다. 다만 ""의 경우를 통과 시킵니다. @Email 보다 아래 나올 @Patten을 통한 정규식 검사를 더 많이 사용합니다.
@Pattern(regexp = )  // 정규식을 검사할 때 사용됩니다.
@Size(min=, max=)  // 문자길이를 제한할 때 사용, int는 불가!

@Max(value = )  // 숫자 value 이하의 값을 받을 때 사용됩니다.
@Min(value = )  // 숫자 value 이상의 값을 받을 때 사용됩니다.

@Pattern(regexp = )	// 정규표현식으로 검증식 세울 수 있다.

@Positive  // 값을 양수로 제한합니다.
@PositiveOrZero  // 값을 양수와 0만 가능하도록 제한합니다.

@Negative  // 값을 음수로 제한합니다.
@NegativeOrZero  // 값을 음수와 0만 가능하도록 제한합니다.

@Future  // 현재보다 미래
@Past  // 현재보다 과거

@AssertFalse  // false 여부, null은 체크하지 않습니다.
@AssertTrue  // true 여부, null은 체크하지 않습니다.

@Valid	// 해당 object validation 실행

 

@Valid와 @Validated

  • @Valid : 자바 표준 검증 어노테이션
  • @Validation : 스프링 전용 검증 어노테이션

@Valid와 @Validated은 비슷한 역할을 하지만 @Validated는 group 기능이 추가되어 있다.

하지만 @Validated는 한 곳에서 데이터를 가져오는 것이 아니라 다른 데이터도 함께 사용하기 때문에 group 기능이 자주 사용되지는 않는다.

 

Spring Boot Validation 적용하는 방법

  • Gradle 의존성 추가
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation
implementation group: 'org.springframework.boot', 
name: 'spring-boot-starter-validation', 
version: '2.5.2'
  • Maven 의존성 추가
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-validation -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>2.5.2</version>
</dependency>

*@Valid가 정상적으로 작동하지 않을 경우

Spring Boot 버전이 2.3 이상일 경우에는 validation 의존성을 따로 추가해줘야 한다.

 

BindingResult이란?

BindingResult는 스프링이 제공하는 검증 오류를 보관하는 객체로 스프링에서 제공하는 값 검증 오류 처리 기능이다.

 

BingdingResult 파라미터의 위치는 오류 검증을 진행할 대상 바로 뒤에 위치해야 되며, BindingResult는 모델에 자동으로 포함이 된다.

BindingResult가 사용되면 데이터 바인딩 시 오류가 발생할 경우 오류 정보를 BindResult에 담은 채로 해당 컨트롤러가 호출이 되지만,

BindingResult가 사용되지 않을 경우에는 오류가 발생하면 4xx 컨트롤러가 실행되지 않고 에러를 발생시키면서 에러 페이지로 이동이 된다.

 

BindingResult에 검증 오류를 적용하는 방법

  • 객체의 오류 등으로 바인딩이 실패할 경우 스프링이 오류 내용을 BindResult에 넣어준다.(아래 설명 참조)
  • 개발자가 직접 넣어준다.
  • Validator 사용

 

BindingResult를 통한 오류 메시지 출력

FiledError/ObjectError

  • FieldError 생성자
    • 필드에 오류가 있으면 FieldError 객체를 생성해서 bindingResult에 담는다. 
    • 두 가지의 생성자 제공
      • public FieldError(String objectName, String field, String defaultMessage);
      • public FieldError(String objectName, String field, @Nullable object rejectValue, boolean bindingFailure, @Nullable String[] codes, @Nullable Object[] arguments, @Nullable String defaultMessage)
  • ObjectError 생성자
    • 특정 필드를 넘어서는 오류가 있으면 ObjectError 객체를 생성해서 bindingResult에 담는다.
    • 두 가지의 생성자 제공
      • public ObjectError(String objectName, String field, String defaultMessage);
      • public ObjectError(String objectName, String field, @Nullable object rejectValue, boolean bindingFailure, @Nullable String[] codes, @Nullable Object[] arguments, @Nullable String defaultMessage)
  • 파라미터
    • objectName : 오류가 발생한 객체 이름
    • field : 오류 필드
    • rejectedValue : 사용자가 입력한 값
    • bindingFailure : 바인딩 실패/검증 실패 구분 값
    • codes : 메시지 코드
    • arguments : 메시지에 사용되는 인자
    • defaultMessage : 기본 오류 메시지

rejectValue()/reject()

BindingResult는 검증해야 될 객체 뒤에 선언이 된다. -> BindingResult는 검증해야 할 객체를 알고 있다.

BindingResult가 제공하는 rejectValue(), reject()를 사용하면 FieldError, ObjectError를 생성하지 않고 오류 검증을 진행할 수 있다.

  • rejectValue()
    • void rejectValue(@Nullable String field, String errorCode, @Nullable object[] errorArgs, @Nullable String defaultMessage);
  • reject()
    • void reject(String errorCode, @Nullable object[] errorArgs, @Nullable String defaultMessage);
  • 파라미터
    • field : 오류 필드명
    • errorCode : 메시지 코드
    • errorArgs : 메시지에 사용되는 인자
    • defaultMessage : 기본 오류 메시지