Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

임도현의 성장

Spring-Boot Bean validationn 본문

Spring Boot

Spring-Boot Bean validationn

림도현 2024. 7. 25. 21:22
  Bean Validation 이란?
먼저 Bean Validation은 특정한 구현체가 아니라 Bean Validation 2.0(JSR-380)이라는 기술 표준이다.
쉽게 이야 기해서 검증 애노테이션과 여러 인터페이스의 모음이다. 
Bean Validation을 잘 활용하면, 애노테이션 하나로 검증 로직을 매우 편리하게 적용할 수 있다.

1. validation 의존성 주입 

  • build.gradle 에 의존관계를 추가하면 라이브러리가 추가 된다
implementation 'org.springframework.boot:spring-boot-starter-validation'

 2. 테스트 코드 작성

@Data
public class Item {
     private Long id;
     
     // @NotBlank 빈값 + 공백만 있는 경우를 허용하지 않는다.
     @NotBlank(message = "이름은 필수 입력 값입니다.") 
     private String itemName;
     
     @NotNull(message = "가격은 필수 입력 값입니다.") // null 을 허용하지 않는다
     @Range(min = 1000, max = 1000000) //  범위 안의 값이어야 한다.
     private Integer price;
     
     @NotNull(message = "갯수는 필수 입력 값입니다.")
     @Max(9999) // 최대 9999까지만 허용한다.
     private Integer quantity;
     
     public Item() {
     }
     
     public Item(String itemName, Integer price, Integer quantity) {
     this.itemName = itemName;
     this.price = price;
     this.quantity = quantity;
     }
 }

 


3. Controller 적용해보기 

@GetMapping("/items/add")
public String add(Model model){
    model.addAttribute("item", new Item());
    return "item/addForm";
}

@PostMapping("/items/add")
public String save(@Valid @ModelAttribute("item") Item item, BindingResult bindingResult, Model model, RedirectAttributes redirectAttributes){

    log.info("objectName={}", bindingResult.getObjectName()); // @ModelAttribute name
    log.info("target={}", bindingResult.getTarget()); // 검증해야할 객체
    log.info("item={}", item);

    if (bindingResult.hasErrors()) {
        log.info("errors={}", bindingResult);
        model.addAttribute("item", item);
        return "item/addForm";
    }

    //성공 로직
    Item savedItem = itemRepository.save(item);
    redirectAttributes.addAttribute("itemId", savedItem.getId());
    // 리다이렉트 status 속성 추가 URL에 쿼리 파라미터로 추가될 수 있습니다.
    redirectAttributes.addAttribute("status", true);
    return "redirect:/basic/items/{itemId}";
}

 

  • @ModelAttribute는 요청 파라미터를 자동으로 객체 필드에 바인딩하고, 해당 객체를 모델에 추가하는 매우 편리한 어노테이션입니다
  • @Valid 유형성 검증을 위한 어노테이션 
  • 순서가 중요 @ModelAttribute 앞에 @Valid가 있어야 합니다
  • Item 상품을 등록할때 hasErrors() 메서드를 통해 Item객체에 설정한 유효성 검사에 문제가 있는지 확인하고 문제가 있을시 다신 이전 View로 보내주면 된

4. html 작성

<form th:action th:object="${item}" method="post">
        <div>
            <label for="itemName" >상품명</label>
            <input type="text" id="itemName" name="itemName" th:field="*{itemName}" class="form-control" placeholder="이름을 입력하세요">
            <div class="field-error" th:errors="*{itemName}">
                상품명 오류
            </div>
        </div>
        <div>
            <label for="price">가격</label>
            <input type="text" id="price" th:field="*{price}" class="form-control" placeholder="가격을 입력하세요">
            <div class="field-error" th:errors="*{price}">
                가격 오류
            </div>
        </div>
        <div>
            <label for="quantity">수량</label>
            <input type="text" id="quantity" name="quantity" th:field="*{quantity}" class="form-control" placeholder="수량을 입력하세요">
            <div class="field-error" th:errors="*{quantity}">
                수량 오류
            </div>
        </div>
        <hr class="my-4">
        <div class="row">
            <div class="col">
                <button class="w-100 btn btn-primary btn-lg" type="submit">상품 등록</button>
            </div>
            <div class="col">
                <button class="w-100 btn btn-secondary btn-lg"
                        th:onclick="|location.href='@{/basic/items}'|"
                        type="button">취소</button>
            </div>
        </div>
        
    </form>

 


5. 실행 

아무것도 입력하지 않을때

 

@Range 가격 범위를 벗어 났을때


6. message.properties

  • 위에 사진을 보면 상품을 아무것도 안적었을때는 message값이 출력이 되는데 왜 @Range 오류는 다른 메세지가 나타나는 걸까 ?
  • log.info를 찍어보면 이름을 알려준다 
log.info("errors={}", bindingResult);
codes [NotBlank.item.itemName,NotBlank.itemName,NotBlank.java.lang.String,NotBlank];
codes [Range.item.price,Range.price,Range.java.lang.Integer,Range];
  • message.properties 에 1순위 코드 이름을 작성후 원하는 메세지를 담으면 된다
NotBlank.itemName=이름은 필수 입력 값입니다.
Range.item.price=가격은 {2} ~ {1} 까지 허용합니다.

 

참고 자료

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


 

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

Spring-Boot @Transactional 트랜잭션 전파  (0) 2024.09.15
Spring-Boot H2 데이터베이스 설정과 연결  (1) 2024.09.02
Spring-Boot MyBatis  (0) 2024.09.01
Spring-Boot Cookie Session  (2) 2024.08.13
Spring-Boot Interceptor  (38) 2024.07.26