[Spring Boot] thymleaf 로 유효성검사 / BindingResult

seulki·2022년 11월 30일
1

[springboot]

목록 보기
16/27

🎈BindingResult 객체

  • 값이 담기는 객체(Item)에 값이 잘 담기지 않고 이슈 발생 시,
    BindingResult 객체에 값이 담긴다.

  • 스프링이 제공하는 검증 오류를 보관하는 객체, 검증 오류가 발생하면 여기에 보관

  • 주의) BindingResult는 검증할 대상 객체 바로 다음에 와야한다. 순서가 중요!
    -> ex)

  • BindingResult는 Model에 자동으로 포함된다.

  • bindingResult 객체에 에러 내용을 담는다.



👌 StringUtils

  • 스프링프레임워크에서 제공하는 유틸
  • 자바의 String 클래스가 제공하는 문자열 관련 기능을 강화한 클래스
  • 파라미터 값으로 null을 주더라도 절대 NullPointException을 발생시키지 않음.

  • !StringUtils.hasText(item.getItemName())
    -> 값이 있을 경우에는 true, 공백이나 null이 들어올 경우에는 fasle를 반환한다.


✨ FieldError 객체

  • field단위의 error를 처리하는 spring 제공해주는 객체
  • 파라미터가 3개인 경우-> 값을 저장할 대상 객체, field, 기본 에러메세지
    -> 에러가 발생하면, 입력했던 값들은 사라지고 에러메세지만 출력된다.


  • 파라미터가 7개인 경우


    FieldError param -> 파라미터 7가지
    - objectName : 오류가 발생한 객체이름
    - field : 오류 필드
    - rejectedValue : 사용자가 입력한 값(거절된 값) -> 사용자가 입력값 출력 + 에러메세지
    - bindingFailure : 타입오류와 같은 바인딩 실패인지를 구분
    - codes : 메세지 코드
    - arguments : 메세지에서 사용하는 인자
    - defualtMessage : 기본 오류 메세지


🎈 에러메세지 설정하기 -> errors.properties

  • 파라미터에 직접 에러메세지를 써 줄 수 있지만, 에러메세지를 다른 설정 파일에 모아놓고, 다른 곳에서 에러메세지만 불러다가 쓸 수 있다.
  • 왼쪽 resources 폴더에 errors.properties 파일 생성하기


  • 스프링에 설정파일로 등록하기 -> application.properties

  • spring.messages.basename=[properties 파일이름]


  • errors.properties 설정파일에 에러메세지 입력하기

    -> 자바파일에서 이 부분을 입력하게 되면 매핑되어, 메세지가 출력되게 된다.

  • 배열에 여러 메세지 코드를 넣을 수가 있는데, 첫번째 코드가 매핑이 되지 않으면, 두번째 코드로 넘어가게 되고, 두번째 메세지 코드도 매핑되지 않는다면, 직접 입력한 맨 마지막 파라미터 값인 "default message"가 출력된다.
    -> 만약 기본 에러메세지 defualtMessage 부분이 null이라면 페이지 자체에서 에러가 발생하게 된다.


  • 고정값으로 입력할수도 있지만, 값이 변경될 수 있기 때문에, index번호로 적어주고 , 정확한 값은 파라미터에 적어준다.
  • new Object[] {1000, 10000} -> {0}에 1000 / {1}에 10000이 대입된다.

  • 에러메세지를 직접 입력하지 않고, 설정파일로 불러와도 잘 출력이 된다.


✨ 데이터 타입이 맞지 않을 때 에러메세지 설정하기

  • Integer 타입 부분에 String을 입력하게 되면 에러메세지가 출력된다.

  • 스프링이 에러메세지를 BindingResult에 담아주고, Model에 담기고 -> 타임리프 -> 출력

  • 타입 에러만 따로 에러메세지를 설정해줄수가 있음.

  • 타입에러 별로 에러메세지 설정하기



  • 🗝️ItemController.java -> FieldError 파라미터 3개인 경우 / 에러발생 시 사용자 입력 값 미출력
@PostMapping("/add")
public String saveV7(Item item, BindingResult bindingResult,
					RedirectAttributes redirectAttributes){

		if(!StringUtils.hasText(item.getItemName())) {
			bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수입니다."));
		}
		
		if(item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
			bindingResult.addError(new FieldError("item", "price", "가격은 1,000이상 1,000,000 미만으로 입력가능합니다."));
		}
				
		if(item.getQuantity() == null || item.getQuantity() >= 10000) {
			bindingResult.addError(new FieldError("item", "quantity", "수량은 10000개 미만으로 가능합니다."));
		}
		//검증에 실패하면 다시 입력 폼으로
		if(bindingResult.hasErrors()) {
			System.out.println("errors = " + bindingResult);
			return "basic/addForm";
		}

		Item savaItem = itemRepository.save(item);
		redirectAttributes.addAttribute("itemId", savaItem.getId());
		redirectAttributes.addAttribute("status", true);
				
		return "redirect:/basic/items/{itemId}" ;
	}
  • addForm.html

    -> 타임리프는 스프링의 BindingResult를 활용해서 편리한 오류 표현기능제공
    -> 에러내용을 "*{itemName}" 에 담아서 가져온다.
    "상품 이름은 필수입니다" 라는 에러 내용을, 앞에있는 "itemName"에 담는다.
    ex)
    -> th:field : BindingResult가 제공하는 오류에 접근 할 수 있다.
    ex)
    -> th:errorclass : th:field에서 지정한 필드에 오류가 있으면 해당 class를 추가
    ex)
    ->th:errors : 해당 필드에 오류가 있는 경우에 태그를 출력한다. th:if의 편의 기능이다.
    ex) 만약 에러가 있다면 태그 출력

  • 에러 클래스 css적용
<form action="item.html" th:object="${item}" th:action method="post">
    <div>
		<label for="itemName">상품명</label> 
		<input type="text" id="itemName" th:field="*{itemName}"
        th:errorclass="field-error" 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}"
        th:errorclass="field-error" class="form-control" placeholder="가격을 입력하세요">
		<div class="field-error" th:errors="*{price}">가격 오류</div>			
	</div>
	<div>
		<label for="quantity">수량</label> 
		<input type="text"  id="quantity" th:field="*{quantity}" 
        th:errorclass="field-error" class="form-control" placeholder="수량을 입력하세요">
		<div class="field-error" th:errors="*{quantity}">수량 오류</div>
	</div>
profile
웹 개발자 공부 중

0개의 댓글