스프링 mvc - 검증 Bean Validation

meluu_·2024년 1월 16일
0

스프링

목록 보기
21/27
post-thumbnail

🌿 시작하기 앞서


스프링 부트 3.2.1 버전을 기준으로 작성됨

Bean Validation : Bean Validation 2.0(JSR-380)이라는 기술 표준

  • 검증 애노테이션과 여러 인터페이스의 모음
  • 일반적으로 사용하는 구현체는 하이버네이트 Validator
  • ORM과는 관련 없음

✔️ Bean Validation


의존관계 추가
//build.gradle

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

검증 애노테이션

@NotBlank : 빈값, 공백 만 있는 경우를 허용 x
@NotNoull : null 허용 x
@Range(min,max) : 범위 안의 값만 허용
@Max(n) : 최대치 설정

이를 사용하면 이전에 사용했던 WebDataBinder을 사용하지 않아도 된다.

스프링 부트는 자동으로 글로벌 Validator로 등록

  • LocalValidatorFactoryBean을 글로벌 Validator로 등록
    • 검증 애노테이션을 보고 검증 수행
    • FieldError, ObjectError를 생성해서 BindingResult에 담아줌

검증 순서

  1. @ModelAttribute 각각의 필드에 타입 변환 시도
    1. 성공하면 다음으로
    2. 실패하면 typeMismatchFieldError 추가
  1. Validator 적용

바인딩에 성공한 필드만 Bean Validation 적용

타입 에러는 typeMismatch FieldError

에러코드

  • @NotBlank
    • NotBlank.item.itemName
    • NotBlank.itemName
    • NotBlank.java.lang.String
    • NotBlank
// errors.properties

//{0}은 필드명
#Bean Validation 추가
NotBlank={0} 공백X
Range={0}, {2} ~ {1} 허용
Max={0}, 최대 {1}

BeanValidation 메시지 찾는 순서

  1. 생성된 메시지 코드 순서대로 messageSource 에서 메시지 찾기
  2. 애노테이션의 message 속성 사용 @NotBlank(message = "공백! {0}")
  3. 라이브러리가 제공하는 기본 값 사용 : 공백일 수 없습니다.

✔️ 객체 분리


흔히 Dto (데이터 전송 객체)를 만들어서 받는다.
등록 Dto , 수정 Dto 등..

HTML Form -> ItemSaveForm -> Controller -> Item 생성 -> Repository

- 장점 : 전송하는 폼 데이터가 복잡해도 거기에 맞춘 별도의 폼 객체를 사용해서 데이터를 전달 받을 수 있다.
		보통 등록과, 수정용으로 별도의 폼 객체를 만들기 때문에 검증이 중복되지 않는다

- 단점 : 폼 데이터를 기반으로 컨트롤러에서 Item 객체를 생성하는 변환 과정이 추가된다.
ItemSaveForm (Dto)
@Data
public class ItemSaveForm {

 @NotBlank
 private String itemName;
 
 @NotNull
 @Range(min = 1000, max = 1000000)
 private Integer price;
 
 @NotNull
 @Max(value = 9999)
 private Integer quantity;
}
Controller
@PostMapping("/add")
 public String addItem(@Validated @ModelAttribute("item") ItemSaveForm form,
					    BindingResult bindingResult, RedirectAttributes redirectAttributes) {
	
    // 필요한 필드 넣어서 생성자 생성
	Item item = new Item(생성자 사용);
    
}

수정도 Dto를 만들어서 필요한 필드 넣고 받아주면 된다.


✔️ HTTP 메시지 컨버터 (JSON)


@ModelAttribute 는 HTTP 요청 파라미터 (쿼리, Post Form) 해당

@RequestBody 는 HTTP Body 데이터 객체변환에 사용 (API JSON 요청)

@Slf4j
@RestController
@RequestMapping("/validation/api/items")
public class ValidationApiController {

    @PostMapping("/add")
    public Object addItem(@RequestBody @Validated ItemSaveForm form, BindingResult bindingResult) {
        log.info("API 컨트롤러 호출");

        if (bindingResult.hasErrors()) {
            log.info("검증 오류 발생 errors={}", bindingResult);
            return bindingResult.getAllErrors();
        }
        
        log.info("성공 로직 실행");
        return form;

    }
}

API 3가지 경우

  • 성공 요청: 성공
  • 실패 요청: JSON을 객체로 생성하는 것 자체가 실패함
  • 검증 오류 요청: JSON을 객체로 생성하는 것은 성공했고, 검증에서 실패함

타입에러등으로 JSON을 Dto로 생성하지 못하면 컨트롤러 자체가 호출되지 않고 Validator도 역시 실행되지 않는다.

HttpMessageConverter 단계에서 실패하면 예외가 발생
예외 처리 필요

@ModelAttribute vs @RequestBody

@ModelAttribute

  • 필드 단위로 정교하게 바인딩이 적용
  • 특정 필드가 바인딩 되지 않아도 나머지 필드는 정상 바인딩
  • Validator를 사용한 검증도 적용

@RequestBody

  • HttpMessageConverter 단계에서 JSON 데이터를 객체로 변경하지 못하면 이후 단계 자체가 진행되지 않고 예외가 발생
  • 컨트롤러도 호출X,Validator 적용 불가


🔖 학습내용 출처

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

profile
열심히 살자

0개의 댓글