[Spring] Bean Validation

성유진·2025년 2월 17일

프로젝트를 진행하면서 예외처리를 잘 하고 싶었는데 마음대로 되지 않아 주먹구구식으로 일단 개발하였다. 하다가 멈춰두었다. 얼른 다시 시작해....

암튼 그래서 미루고 미루다가... 사두었던 스프링 MVC2 강의가 생각나서 살펴 보았는데, 예외처리 관련되니 파트가 있어서 시작하였다.

예외처리 파트만 들을까..... 라고 생각하였는데,
처음부터 시작 안하면 못 버티는 자아 vs 효율 추구 자아
두 개의 자아가 싸우다가 결국 타협을 보았다.
처음부터는 안 보고 그냥 재밌어보이는 파트만 듣기~
두 가지 자아 중 하나가 아니라 그냥 도파민이 이긴 것 같지만 아무튼 들었으니까 괜찮은 것 같다.

사족이 정말 길었는데
그래서 Bean Validation 파트를 들었다.
그리고 그 다음에 예외처리 파트를 들을 것이다. 후속도 기대 부탁합니다.

@Valid와 @Validated

@Valid 라는 어노테이션으로
요청 메시지의 body로 전달되는 객체의 필드값을 쉽게 예외처리할 수 있다더라
고 전해들어서 그냥 사용하였다.

@NotNull, @Range, @Max 등등.. 별걸 다 사용할 수 있어 아주 편리하더라!

근데 강의를 들어보니 Valid가 아니라 Validated도 사용할 수 있다고 한다
잉? 두개가 뭐가 다른가 했더니

@Validated 는 스프링 전용 검증 애노테이션
@Valid는 자바 표준 검증 애노테이션

이라고 한다.

Groups

참고로 @Validated는 groups라는 기능이 있어서
하나의 모델 객체에 여러 그룹들을 만들어서 validation 을 적용시킬 그룹을 지정할 수 있다.

강의에서 groups를 활용한 예시 코드이다.

아무래도 꽤나 많이 더럽다

그래서 잘 사용하지 않는다고 한다..~
이미 원래 개발하던 방식처럼 DTO로 별도의 객체로 나누어서 관리하는 것이 일반적이라고 한다.
실제 개발할 때에도 애초에 모델 객체의 필드들을 모두 사용하지 않고 요청으로 전달받는 객체가 다르니 이렇게 관리하는 것이 더 편하다!

Bean Validation

다시 Bean Validation 으로 돌아오자
그래서 이 친구가 무엇이냐면 인터페이스이다.
Bean Validation 자체는 검증 어노테이션에 대한 명세인 셈이다.

구현체로는 주로 Hibernate validator를 사용한다.

사용할 때에는 build.gradle에 아래와 같이 의존관계를 추가해 주면 된다.
implementation 'org.springframework.boot:spring-boot-starter-validation'

그러면 이렇게 인터페이스인 Bean Validation에 해당하는 jakarta validation과
구현체에 해당하는 Hibernate validator가 라이브러리에 설치된 것을 확인할 수 있다.

그리고 해당 라이브러리가 존재하면 스프링부트가 LocalValidatorFactoryBean을 글로벌 Validator로 등록해준다.

그리고 이렇게 빈으로 등록하면 에러 코드도 설정해준다.
에러 코드에 따라서 에러 메시지도 properties.message에 이렇게 등록해서 사용 가능하다.

NotBlank=공백X
Range={2} ~ {1} 허용
Max=최대 {1}

그리고 검증 오류가 발생하면, FieldError , ObjectError 를 생성해서 BindingResult 에 담아준다.
강의에서는 컨트롤러에 BindResult를 인자로 받고, 그에 따라서 타임리프에 적절한 에러 메시지를 띄우는 것까지 실습해보았다.

근데 사실 실제로 개발하는 경우, api 응답을 주고 받아서 이 경우의 에러를 어떻게 처리하는가! 가 궁금하다

이런 식으로 BindingResult가 없으면 검증에 실패하면,
MethodArgumentNotValidException 예외가 발생하고 그냥 400 에러를 반환한다.

@PostMapping
public String createUser(@Valid @RequestBody UserDto userDto) {
  return "회원 가입 성공!";
}

이 에러를 어떻게 잘 처리할 수 있을까..?
이건 이제 다음 강의를 들어야 알 수 있다. 듣기전에 스스로 고민도 조금 해보면 좋을 것 같다!
아무튼 얼른 공부해보고 돌아오도록 하겠다.

2개의 댓글

comment-user-thumbnail
2025년 2월 21일

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/MethodArgumentNotValidException.html

MethodArgumentNotValidException.class의 javadoc에 적힌 Method 보시면 어떤 필드에서 검증 실패했는지 나오는 메서드가 있습니다. 이걸 이용해서 커스텀하면 더 잘 처리한게 될 수 있겠죠~

1개의 답글