Bean Validation

HUSII·2023년 5월 9일
0

스프링 MVC

목록 보기
4/5

클라이언트로부터 받은 정보를 검증할 때 사용하는 것이
Bean Validation

어노테이션을 이용해서 간단하게 검증할 수 있다


먼저 build.gradle에 의존관계를 추가해야함

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

검증할 객체에 검증 어노테이션을 삽입한다

public class Item {
  private Long id;
  @NotBlank
  private String itemName;
  @NotNull
  @Range(min = 1000, max = 1000000)
  private Integer price;
  @NotNull
  @Max(9999)
  private Integer quantity;
}

이외에도 다향한 어노테이션이 있다

@NotNull vs @NotEmpty vs @NotBlack
@NotNull은 null 일때만 에러
@NotEmpty는 @NotNull + "" 일때 에러
@NotBlank는 @NotEmpty + " " 일때 에러
@NotBlank가 가장 강하다


위의 객체를 컨트롤러에 적용하면

@PostMapping("/add")
  public String addItem(@Validated @ModelAttribute Item item, BindingResult
  bindingResult, RedirectAttributes redirectAttributes) {
  if (bindingResult.hasErrors()) {
  log.info("errors={}", bindingResult);
  return "validation/v3/addForm";
  }
  //성공 로직
  Item savedItem = itemRepository.save(item);
  redirectAttributes.addAttribute("itemId", savedItem.getId());
  redirectAttributes.addAttribute("status", true);
  return "redirect:/validation/v3/items/{itemId}";
}

Bean Validation을 사용하기 위해
검증할 객체에 @Valited를 붙혀주고, 바로 옆에
BindingResults 객체를 붙혀줘야 한다.

검증순서
1. @ModelAttribute 각가의 필드에 타입 변환 시도

    1. 성공하면 다음으로
    1. 실패하면 typeMismatch로 FieldError 추가
  1. Validator 적용

바인딩에 성공한 필드(타입 변환 성공)만 Bean Validation을 적용한다
그리고 bindingResults.hasErrors() 로 에러가 있는지 체크하고
있다면 이전 폼 주소로 보낸다


에러가 있다면 이를 클라에 전달해 보여줘야 한다.
이를 위해 에러 메시지용 파일을 생성한다.
먼저 application.properties에 해당 파일을 지정해준다

spring.messages.basename=errors

그다음 erros.properties 파일에서 에러 메시지를 설정해준다

(오류코드.객체이름.필드명=에러메시지)
range.item.price=가격은 {0} ~ {1} 까지 허용합니다.
// {0], {1] 로 인자값을 출력할 수  있다
// 객체이름과 필드명을 넣지 않아도 알아서 출력됨
// -> 자세한 것이 우선
// 오류코드.타입 가능 -> typeMismatch.java.lang.Integer
typeMismatch=타입이 맞지 않습니다.
// 타입을 잘못 받았을 때 오류 메시지

Bean Validation에서 특정 필드가 아닌 오브젝트 관련 오류가 생길 수 있다
이때는 오브젝트 오류 관련 부분만 자바 코드로 작성하는 것을 권장한다

public String addItem(@Validated @ModelAttribute Item item, BindingResult
bindingResult, RedirectAttributes redirectAttributes) {
  //특정 필드 예외가 아닌 전체 예외
  if (item.getPrice() != null && item.getQuantity() != null) {
  int resultPrice = item.getPrice() * item.getQuantity();
  if (resultPrice < 10000) {
  bindingResult.reject("totalPriceMin", new Object[]{10000,
  resultPrice}, null);
  }
  }
  if (bindingResult.hasErrors()) {
  log.info("errors={}", bindingResult);
  return "validation/v3/addForm";
}

이때 bindingResult.reject() 메서드를 이용해서 오류 메시지를 추가해준다
bindingResult.reject(오류코드, 메시지로 출력할 인자들, 디폴트메시지)
bindingResult.rejectValue(필드명, 오류코드, 메시지로 출력할 인자들, 디폴트메시지)


@Validated는 @RequestBody도(API JSON) 가능하다

하지만 @RequestBody는 @ModelAttribute와 다르게
필드 단위가 아닌 객체 단위로 검증한다.
-> 타입이 맞지 않는다면 객체 자체가 생성이 되지 않는다
-> Validator를 적용할 수 없다

profile
공부하다가 생긴 궁금한 것들을 정리하는 공간

0개의 댓글