@RequestBody와 @Valid의 동작 방식
동작 원리 설명
@RequestBody @Valid ItemSaveForm form, BindingResult br
의 경우:
@RequestBody
는 클라이언트 요청의 HTTP 본문을 Java 객체로 변환합니다. 이 과정은 HttpMessageConverter가 담당합니다.- 변환 중에 JSON → Java 객체로 매핑 시 타입 에러가 발생하면, Spring은 컨트롤러 메서드에 접근하지 않고 예외(
HttpMessageNotReadableException
등)를 던집니다. - 따라서,
BindingResult
에 에러가 바인딩되지 않고, 컨트롤러 메서드 실행 전에 예외가 발생하여 정상 동작하지 않습니다.
@Valid ItemSaveForm form, BindingResult br
의 경우:
@Valid
는 Spring Validator를 사용하여 객체에 대한 유효성 검사를 수행합니다.- 여기서 중요한 점은 타입 변환이 성공한 후에 유효성 검증이 실행됩니다.
- 만약 유효성 검증 에러가 발생하면,
BindingResult
에 에러가 추가되고 컨트롤러 메서드가 정상적으로 실행됩니다.
차이점 요약
구분 | @RequestBody @Valid | @Valid |
---|---|---|
데이터 소스 | JSON / XML (Request Body) | 요청 파라미터 |
바인딩 실패 시 동작 | 예외 발생 (컨트롤러 도달 X) | BindingResult에 에러 저장 |
검증 실패 시 동작 | 검증 후 컨트롤러 도달, BindingResult 사용 가능 | 동일 |
해결 방법
만약 @RequestBody
를 사용하는 경우에도 타입 변환 에러를 컨트롤하고 싶다면, 예외를 처리하는 방식으로 해결할 수 있습니다:
1. @ControllerAdvice
를 사용한 글로벌 예외 처리
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(HttpMessageNotReadableException.class)
public ResponseEntity<String> handleHttpMessageNotReadable(HttpMessageNotReadableException ex) {
return ResponseEntity.badRequest().body("Invalid request body: " + ex.getMessage());
}
}
2. 커스텀 메시지 반환
컨트롤러에서 @RequestBody
를 제거하거나, 에러 메시지를 사용자 정의로 처리.
정리
@RequestBody
는 JSON 파싱 단계에서 에러가 발생하면BindingResult
로 에러를 전달하지 못합니다.@Valid
는 파싱이 끝난 후에 실행되므로, 타입 변환 문제 없이 유효성 검증 에러를BindingResult
로 처리할 수 있습니다.
이러한 차이를 이해하여 상황에 맞게 처리 방식을 선택하면 됩니다.
'spring' 카테고리의 다른 글
SpringMVC ArgumentResolver (0) | 2024.12.02 |
---|---|
Entity 클래스와 DTO를 분리하는 이유 (0) | 2024.11.30 |
도메인 모델 패턴 vs 트랜잭션 스크립트 패턴 (0) | 2024.11.25 |
자바 접근제어자 개념과 JPA @Embeddable에서 기본생성자에 proteced를 사용하는 이유 (0) | 2024.11.24 |
JPA기초 @Entity & @Id & @GeneratedValue & 영속성 컨텍스트 (0) | 2024.11.23 |
댓글