[Spring] Bean Validation (검증) - 1

2024. 10. 31. 11:29·Spring Framework

해당 예제는 다음과 같은 기술 스택을 사용했습니다.

  • JDK 11
  • Spring Boot
  • ThymeLeaf

 

1. Bean Validation이란?

Bean Validation은 Java EE 환경에서 표준으로 제공되는 유효성 검증 프레임워크로, JSR-380(Bean Validation 2.0) 표준에 따라 정의된다. 애노테이션 기반으로 도메인 모델의 필드에 유효성 검증 규칙을 선언하여 자동으로 검증을 수행할 수 있게 해준다.

 

Spring Boot는 기본적으로 Hibernate Validator를 통합하여 Bean Validation을 지원한다. Hibernate Validator는 Bean Validation의 레퍼런스 구현체로, 다양한 유효성 검증 기능을 제공한다.

 

Bean Validation은 다양한 유효성 검증 애노테이션을 제공한다.

  • @NotNull: 값이 null이 아님을 검사.
  • @NotEmpty: 문자열, 컬렉션 등이 비어있지 않음을 검사.
  • @NotBlank: 문자열이 공백이 아님을 검사.
  • @Size: 문자열, 배열, 컬렉션 등의 크기를 검사.
  • @Min, @Max: 숫자의 최소값과 최대값을 검사.
  • @Email: 이메일 형식을 검사.
  • @Pattern: 정규식을 사용하여 값을 검사.

2. 프로젝트 준비

의존성 추가

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

 

3. Bean Validation 시작하기

도메인 모델에 검증 애노테이션 적용

Item 클래스를 하나 생성 후 검증 애노테이션을 추가한다.

public class Item {

    private Long id;

    @NotBlank(message = "상품 이름은 필수입니다.")
    private String itemName;

    @NotNull(message = "가격은 필수입니다.")
    @Range(min = 1000, max = 1000000, message = "가격은 1,000원에서 1,000,000원 사이여야 합니다.")
    private Integer price;

    @NotNull(message = "수량은 필수입니다.")
    @Max(value = 9999, message = "수량은 최대 9,999까지 허용됩니다.")
    private Integer quantity;

    // getters and setters
}

 

Bean Validation 테스트 코드 작성

@SpringBootTest
public class BeanValidationTest {

    @Test
    void beanValidation() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();

        Item item = new Item();
        item.setItemName(" "); // 공백 문자열
        item.setPrice(0);
        item.setQuantity(10000);

        Set<ConstraintViolation<Item>> violations = validator.validate(item);
        for (ConstraintViolation<Item> violation : violations) {
            System.out.println("오류 필드: " + violation.getPropertyPath());
            System.out.println("오류 메시지: " + violation.getMessage());
        }
    }
}

 

그럼 다음과 같은 값이 콘솔에 나타날 것이다.

 

 

4. 스프링과 Bean Validation 통합

컨트롤러에서 검증 적용

Controller의 매개변수에서 @Validated 애노테이션을 사용하여 검증을 활성화한다.

 

@PostMapping("/add")
public String addItem(@Validated @ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
    if (bindingResult.hasErrors()) {
        return "validation/v3/addForm";
    }
    // 성공 로직
}

 

  • @Validated: 스프링 프레임워크에서 제공하는 검증 애노테이션
  • BindingResult: 검증 오류 정보를 담는 객체 (무조건 바인딩 할 객체 매개변수 뒤에 선언해줘야 함)

 

 

5. 에러 메시지 커스터마이징

메시지 소스 설정

messages.properties 또는 errors.properties 파일에 커스텀 에러 메시지를 정의할 수도 있다.

NotBlank.item.itemName=상품 이름은 필수입니다.
Range.item.price=가격은 {2}에서 {1} 사이여야 합니다.
Max.item.quantity=수량은 최대 {1}까지 허용됩니다.

 

메시지 코드 우선순위

  1. NotBlank.item.itemName
  2. NotBlank.itemName
  3. NotBlank.java.lang.String
  4. NotBlank

 

6. 오브젝트 레벨 검증

필드 단위가 아닌 객체 전체에 대한 검증이 필요한 경우, 직접 자바 코드를 통해 검증한다. 예를들어 "아이템의 수량 * 가격이 10000원이하라는 조건"이 생성된다면 어노테이션 선언으로 검증하기가 어려울 것이다. 그래서 직접 자바 코드를 통해 검증하는것이 낫다.

// 검증 예시 코드
if (item.getPrice() != null && item.getQuantity() != null) {
    int totalPrice = item.getPrice() * item.getQuantity();
    if (totalPrice < 10000) {
        bindingResult.reject("totalPriceMin", new Object[]{10000, totalPrice}, null);
    }
}

 

 

7.  다른 API (아이템 수정 기능)에도 검증 적용하기

수정 시에도 검증이 필요하므로, 수정용 컨트롤러 메서드에 @Validated를 적용한다.

@PostMapping("/{itemId}/edit")
public String edit(@PathVariable Long itemId, @Validated @ModelAttribute Item item, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return "validation/v3/editForm";
    }
    // 수정 로직
}

 

 

저장과 수정 검증 조건이 같다면 상관이 없겠지만 다르다면 하나의 도매인 객체에 모든 검증 로직을 선언하기 어려울 것이다. 예를들자면 저장 할 때의 검증로직과 수정 할 때의 검증 로직이 다를 수 있기 때문이다. 다음 포스팅에서는 이러한 문제점을 해결하기 위한 해결책을 포스팅하겠다.

다음 포스팅:

[Spring] Bean Validation (검증) - 2

 

 

Reference

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

https://hibernate.org/validator/

'Spring Framework' 카테고리의 다른 글

[Spring] 예외 처리와 오류 페이지  (0) 2024.11.12
[Spring] Bean Validation (검증) - 2  (0) 2024.11.04
[Spring] 스프링 메시지, 국제화  (1) 2024.10.29
[Spring] Argument Resolver 란?  (0) 2024.10.24
@Transactional을 선언해도 내부 메서드를 실행 시 ROLLBACK이 되지 않는 문제  (0) 2024.08.03
'Spring Framework' 카테고리의 다른 글
  • [Spring] 예외 처리와 오류 페이지
  • [Spring] Bean Validation (검증) - 2
  • [Spring] 스프링 메시지, 국제화
  • [Spring] Argument Resolver 란?
Economy98
Economy98
공부하고 기록하기
  • Economy98
    Economy_Dev
    Economy98
  • 전체
    오늘
    어제
    • 분류 전체보기 (74)
      • Spring Framework (11)
      • BOJ, Programmers (22)
      • Java (4)
      • JDBC (6)
      • JPA (9)
      • Spring Transaction (3)
      • Algorithm (1)
      • Web (5)
      • Projects (2)
        • 쇼핑몰 프로젝트 (0)
        • 열람실 & 도서관 프로젝트 (2)
      • Network (2)
      • 나의 공부방 (5)
      • 끄적끄적 (1)
      • Error Log (3)
      • CS (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • Github
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    브루트포스 알고리즘
    jdbc
    자바 문제 풀이
    자바
    스프링
    java
    백준 자바 풀이
    트랜잭션
    자바 문제
    다이나믹 프로그래밍
    백준
    restful api
    백준 풀이
    JPA
    예외 처리
    Spring
    그리디 알고리즘
    스프링부트
    정렬
    propagation
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
Economy98
[Spring] Bean Validation (검증) - 1
상단으로

티스토리툴바