좋은 질문입니다! "왜 @RequestBody로 모든 걸 처리하지 않고 @ModelAttribute도 필요할까?"라는 의문은 많은 분들이 갖는 질문이에요. 결론부터 말씀드리면:
HTTP 스펙과 브라우저의 동작 방식, 그리고 Spring이 다양한 클라이언트를 지원해야 하기 때문입니다.
아래에 좀 더 구체적으로 설명드릴게요.
HTML <form> 태그를 사용해서 데이터를 전송하면 브라우저는 기본적으로 application/x-www-form-urlencoded나 multipart/form-data 형식으로 전송합니다. 이건 JSON이 아닙니다.
<form action="/submit" method="post">
<input name="name" value="Alice" />
<button type="submit">전송</button>
</form>
이런 폼은 JSON으로 전송되지 않기 때문에, @RequestBody는 데이터를 못 읽어요. 대신 @ModelAttribute는 이 포맷에 맞춰 자동 바인딩을 해줍니다.
@RequestBody는 오직 HTTP 바디에 JSON/XML 등이 있을 때만 동작합니다.
쿼리 스트링이나 폼 파라미터는 신경 쓰지 않아요.
POST /users?role=admin
Content-Type: application/json
{
"name": "Alice",
"age": 30
}
이럴 때 @RequestBody는 role=admin을 모릅니다.
@ModelAttribute는 이런 query string까지 바인딩 가능하죠.
실무에서는 종종 이런 요청이 있습니다:
multipart/form-data)이때는 JSON이 아니라 multipart/form-data를 사용하게 되며, @RequestBody는 이런 요청을 처리할 수 없습니다.
반면 @ModelAttribute는 폼 데이터와 파일 모두를 한 번에 바인딩할 수 있습니다.
| 구분 | @RequestBody | @ModelAttribute |
|---|---|---|
| JSON 기반 API | ✅ | ❌ |
HTML <form> 요청 | ❌ | ✅ |
| 파일 업로드 | ❌ | ✅ (MultipartFile 지원) |
| 쿼리스트링 바인딩 | ❌ | ✅ |
@RequestBody로만 처리해도 되는가?@RequestBody만 써도 됩니다.그 외 경우 (특히 웹에서 폼 제출할 때)는 @ModelAttribute가 필요합니다.
필요하시면, 특정 예제나 시나리오로 비교해드릴게요!