Spring Boot

[Spring Boot] Bean Validation

수수한개발자 2022. 6. 28.
728x90

지금부터 Validation에 대해 알아보겠습니다.

우리가 회원가입을 한다고 했을때 많은 항목중에서 하나를 잘못입력하면 일반적인 웹 애플리케이션이면 어떤것이 잘못되었는지 알려줍니다. 만약 알려주지않고 에러페이지가 나오면 가입하다말고 짜증나서 회원가입을 안하는 경우가 생길 수 도 있습니다. 이를 방지하기 위해 검증처리로직을 Validation이라는것으로 할 수 있습니다.

 

Bean Validation

스프링의 기본적인 validation인 Bean Validation은 클래스의 필드에 특정 annotation을 적용하여 필드가 갖는 제약 조건을 정의하는 구조로 이루어진 검증?, 검사 입니다.

validator가 비즈니스로직이 아니라 그 객체 필드에 대한 유효성 검사를 해줍니다.

 

 

Validation 적용 하기

spring boot 에서 build.gradle에 의존성을 추가해 주어야 합니다.

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

 

Maven 이라면 아래 코드

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

 

Controller

유효성 검사를 할 request 객체 앞에 @Validated 어노테이션을 추가합니다. @Validated 가 붙은 request 객체 뒤에 BindingResult를 붙여주어야 합니다.

@PostMapping("/add")
    public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form, BindingResult bindingResult, RedirectAttributes redirectAttributes) {

        //특정 필드가 아닌 복합 룰 검증
        if (form.getPrice() != null && form.getQuantity() != null) {
            int resultPrice = form.getPrice() * form.getQuantity();
            if (resultPrice < 10000) {
                bindingResult.reject("totalPriceMin", new Object[]{10000, resultPrice}, null);
            }
        }

        //검증에 실패하면 다시 입력폼으로
        if (bindingResult.hasErrors()) {
            log.info("error={}", bindingResult);
            return "validation/v4/addForm";
        }

        //성공로직
        Item item = new Item();
        item.setItemName(form.getItemName());
        item.setPrice(form.getPrice());
        item.setQuantity(form.getQuantity());
        Item savedItem = itemRepository.save(item);

        redirectAttributes.addAttribute("itemId", savedItem.getId());
        redirectAttributes.addAttribute("status", true);
        return "redirect:/validation/v4/items/{itemId}";
    }

 ItemSaveForm

@Data
public class ItemSaveForm {

    @NotBlank
    private String itemName;

    @NotNull
    @Range(min = 1000, max = 1000000)
    private Integer price;

    @NotNull
    @Max(value = 9999)
    private Integer quantity;
}

@NotBlank : 비어있으면 안된다.

@NotNull : 널이면 안된다.

@Range : 1000이상 100000이하

@Max : 9999가 최대값 넘어가면 안됨.

 

이외에도 여러가지 어노테이션들이 있습니다. 여기를 누르시면 이동됩니다.

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

@Email  // 이메일 형식을 검사합니다. 다만 ""의 경우를 통과 시킵니다
@Pattern(regexp = )  // 정규식을 검사할 때 사용됩니다.
@Size(min=, max=)  // 길이를 제한할 때 사용됩니다.

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

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

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

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

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

addForm.html

<input type="text" id="itemName" th:field="*{itemName}"
       th:errorclass="field-error" class="form-control" placeholder="이름을 입력하세요">
<div class="field-error" th:errors="*{itemName}">
    상품명 오류
</div>

thymeleaf 문법으로 th:errorclass="field-error" 를하면 에러가 생기면 field-error 클래스가 생긴다.

th:errors="*{itemName}" 은 from에 정의된 th:object="${item}의 정의된 필드명인 itemName에 대한 에러를 표시한다. 는 뜻이다.

728x90

댓글