Spring에서의 Bean Validation

hoyong.eom·2023년 11월 21일
0

스프링

목록 보기
52/59
post-thumbnail

Spring

Bean Validation

이전 포스팅( Bean Validation )에서 Bean Validation에 대해서 정리를 했었다.

근데... ModelAndView 방식의 Controller와 아니라 API Controller인 경우 Bean Validation 동작후 에러 메시지를 제대로 가져오지 않아 조금 삽질을 했다..

이번 포스팅에서는 API서버에서 Bean Validation을 적용하고 에러 메시지를 커스텀하여 적용하는 방법을 정리하려고 한다.

@ModelAttribute VS @RequestBody

우선 전지전능의 chatgpt에게 물어보았다.

질문)
@ModelAttribute는 errors.properties에서 알아서 가져오는데 @Requestbody는 코딩을 해줘야해?

답변)
@ModelAttribute는 스프링이 폼 데이터를 처리하고 에러 메시지를 errors.properties에서 가져오는 데에 자동으로 도움을 줍니다. 반면에 @RequestBody를 사용할 때에는 수동으로 에러 처리를 해주어야 하며, 에러 메시지를 명시적으로 관리해야 합니다.

김영한님의 Spring-MVC2 강의를 다시 들어보니.. 거기에서도 마찬가지로 말씀하셨다.
즉, @ModelAttribute는 자동으로 errors.properties에서 가져와서 사용하지만, @RequestBody는 내가 직접 메시지를 가져와서 사용해야한다.

좀더 정확히 표현하자면.. thymeleaf의 th:error와 같은 기능들이 알아서 해결해주는것이다. ModelAttribute가 해결해주는건 아니다!!

이제 어떻게 가져올 수 있을까?
메시지를 가져오기 위해서는 아래의 포스팅에서 정리한 내용을 이해하고 있어야한다.

Spring-Validation

MessageSource

스프링은 기본적인 메시지 관리 기능을 제공합니다.

메시지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource를 스프링빈으로 등록하면 되는데, MessageSource는 인터페이스이며 이 구현체인 ResourceBundleMessageSource를 스프링빈으로 등록하면 됩니다.
하지만, 스프링 부트를 사용하면 MessageSource가 자동으로 스프링빈으로 등록되기 때문에 application.properties에 아래와 같이 설정 값만 넣어주면 됩니다.

spring.messages.basename=messages,config.i18n.messages

물론 기본값도 존재합니다.

spring.messages.basename=message

MessageCodeResolver

BindingResult에 존재하는 FieldError와 rejectValue는 내부에서 MessageCodeResolver를 사용해서 오류 코드를 구성합니다.

MessageCodeResolver 아래와 같은 기능을 수행합니다.

  • 검증 오류 코드로 메시지 코드를 생성합니다.
  • MessageCodeResolver인터페이스와 기본 구현체인 DefaultMessageCodeResolver가 존재합니다.
  • rejectValue()reject()는 내부에서 MessageCodeResolver를 통해서 생성된 순서대로 오류 코드를 보관합니다.

따라서 MessageCodeResolver를 기반으로 생성된 오류코드를 순서대로 MessageSource에서 찾아서 사용합니다.

Bean Validation

스프링 부트는 spring-boot-starter-validation 라이브러리를 넣으면 자동으로 Bean Validator를 인지하고 스프링에 통합합니다.

스프링 부트는 자동으로 글로벌 Validator로 등록합니다.
LocalValidatorFactoryBean을 글로벌 Validator로 등록합니다. 이 Validator는 @NotNull같은 애노테이션을 보고 검증을 수행합니다. 이렇게 글로벌 Validator가 적용되어 있기 때문에 @Valid, @Validated만 적용하면 됩니다.
검증 오류가 발생하면 FieldError, ObjectError를 생성해서 BindingResult에 담아줍니다.

기본적으로 Bean Validation은 아래와 같은 순서로 메시지를 찾습니다.

  • 생성된 메시지 코드 순서대로 messageSource에서 메시지 찾기
  • 애노테이션의 message 속성 사용
  • 라이브러리가 제공하는 기본값 사용

RequestBody에서 사용하기

참고
RequestBody의 Validation추가하기
김영한님의 SpringMVC2

참고

해당 포스팅은 아래의 강의를 공부하여 정리한 내용입니다.
김영한님의 스프링 핵심 원리 고급

0개의 댓글