[Spring] Bean Validation (4)

이연우·2025년 7월 26일

TIL

목록 보기
53/100

🧭 @ModelAttribute, @RequestBody

  • @Valid, @Validated
    @ModelAttribute@RequestBody 모두에 적용할 수 있음
  • 다만, 데이터 바인딩 방식과 검증 실패 시 동작완전히 다름

🧷 @RequestBody 사용 시 검증 흐름

📜 DTO 클래스

@Data
public class ExampleRequestDto {
    @NotBlank
    private String field1;

    @NotNull
    @Range(min = 1, max = 150)
    private Integer field2;
}

💡 컨트롤러

@PostMapping("/example")
public Object save(
    @Validated @RequestBody ExampleRequestDto dto,
    BindingResult bindingResult
) {
    if (bindingResult.hasErrors()) {
        return bindingResult.getAllErrors(); // JSON 반환
    }
    return dto;
}

🧪 Rest API 요청 3가지 경우

1. 성공 요청

  • 모든 필드 타입 및 값이 조건을 만족
  • JSON → DTO 변환 성공
  • Validation 통과 → 정상 응답

🖼️ 결과:
→ Controller 정상 호출
→ DTO 반환

2. 변환 실패 (JSON → DTO 불가)

  • 예: field2에 숫자가 아닌 문자열 입력

🖼️ 결과:
JSON 변환 단계에서 실패
→ Controller 호출 ❌
→ Validation 진행 ❌
HTTP 400 Bad Request

⚠️ DTO 변환 실패는 검증 단계까지 가지 못함

3. 검증 실패 (DTO 변환은 성공)

  • 예: field2 = 1000 (조건: 최대 150)

🖼️ 결과:
→ DTO 변환 성공
→ Controller 호출됨
bindingResult.hasErrors() = true
FieldError / ObjectError 응답


🧩 정리: @ModelAttribute vs @RequestBody

항목@ModelAttribute@RequestBody
바인딩 방식필드 단위 바인딩객체 단위 바인딩
실패 시실패한 필드만 제외하고 나머지 검증 진행JSON 전체 변환 실패 시 Controller 호출 ❌
Controller 호출 여부대부분 호출됨JSON 파싱 실패 시 호출 ❌
검증 적용 시점바인딩 후, 개별 필드 기준변환 후, 전체 객체 기준

@ModelAttribute는 일부 실패해도 나머지 필드는 검증 가능
@RequestBody는 객체로 전체 변환이 성공해야 검증 적용 가능

🛠️ 추가 팁

  • bindingResult.getAllErrors()
    FieldError, ObjectError 모두 포함 (자동 JSON 변환됨)
  • Spring은 MessageConverter를 이용해 Error 객체를 JSON으로 응답

📌 DTO 분리의 중요성

  • 등록, 수정, 삭제 요청은 겉보기에 비슷해 보여도 각기 다른 검증 조건을 가질 수 있음
  • 따라서 Request DTOAPI 목적에 맞게 따로 분리해서 사용하는 것이 안전

0개의 댓글