@RequestBody는 HTTP 요청 바디(body)에 담긴 JSON, XML, 기타 데이터를 자바 객체로 자동 변환해주는 Spring MVC 애노테이션입니다.
보통 REST API에서 클라이언트가 JSON 형식으로 데이터를 전송할 때 사용합니다.
클라이언트가 보낸 JSON 데이터를 Java 객체로 바꿔주는 역할을 수행합니다.
@RequestBody로 처리해야겠다고 판단정확한 동작 방식은 다음과 같습니다.
// 요청 바디 예시
{
"title": "뉴스 제목",
"content": "뉴스 내용"
}
@PostMapping("/api/news")
public ResponseEntity<?> createNews(@RequestBody NewsDTO newsDTO) {
// newsDTO.getTitle() → "뉴스 제목"
// newsDTO.getContent() → "뉴스 내용"
}
{
"title": "Spring 뉴스",
"content": "Spring Boot의 @RequestBody 정리"
}
@RequestBody를 통해 DTO 객체로 자동 매핑됩니다.@Getter @Setter
public class NewsDTO {
private String title;
private String content;
// 기본 생성자 (Jackson이 내부적으로 사용)
public NewsDTO() {}
// toString() 메서드를 추가하면 디버깅 시 편리함
@Override
public String toString() {
return "NewsDTO{" +
"title='" + title + '\'' +
", content='" + content + '\'' +
'}';
}
}
@RequestBody는 내부적으로 Jackson(ObjectMapper)을 사용해 JSON → 객체로 변환합니다.toString()은 디버깅 시 JSON → DTO 변환이 잘 됐는지 확인할 때 유용합니다.@RestController
@RequestMapping("/api")
public class NewsController {
private final NewsService newsService;
// 생성자 주입 (권장 방식)
public NewsController(NewsService newsService) {
this.newsService = newsService;
}
@PostMapping("/news")
public ResponseEntity<String> addNews(@RequestBody NewsDTO newsDTO) {
// 여기서 newsDTO는 이미 JSON에서 변환된 Java 객체임
System.out.println("받은 데이터: " + newsDTO.toString());
// 서비스 레이어로 전달하여 비즈니스 로직 처리
newsService.saveNews(newsDTO);
// 응답 반환
return ResponseEntity.ok("제목: " + newsDTO.getTitle() + "인 뉴스가 저장되었습니다");
}
}
@RequestBody는 JSON 요청 바디를 newsDTO 객체에 자동 매핑합니다.ResponseEntity.ok(...)를 통해 HTTP 200 응답과 함께 메시지를 반환합니다.POST /api/news HTTP/1.1
Host: localhost:8080
Content-Type: application/json
{
"title": "뉴스 제목",
"content": "뉴스 내용"
}
Content-Type: application/json은 반드시 포함되어야 합니다.@RequestBody가 동작합니다.Spring은 요청이 들어오면 다음과 같은 과정을 거칩니다.
HttpMessageConverter를 찾아서 적용MappingJackson2HttpMessageConverter 선택 MappingJackson2XmlHttpMessageConverter 선택HttpMessageNotReadableException 발생Jackson이 JSON을 객체로 변환할 때 프로퍼티 이름 매칭, 기본 생성자 호출, setter 메서드 호출 등의 과정을 거칩니다. 따라서 DTO 클래스에는 반드시 기본 생성자와 setter 메서드가 있어야 합니다.
@RequestBody vs 다른 애노테이션 비교| 애노테이션 | 데이터 출처 | 데이터 형식 | 용도 | 실제 예시 |
|---|---|---|---|---|
@RequestBody | 요청 바디 | JSON/XML | REST API | 회원가입, 게시글 작성 등 |
@RequestParam | 쿼리스트링 | key=value | 단순 파라미터 | 검색어, 페이지 번호 등 |
@PathVariable | URL 경로 | URL의 일부 | RESTful URL | 회원 ID, 상품 ID 등 |
@ModelAttribute | 요청 파라미터 | 폼 데이터 | HTML 폼 처리 | 로그인 폼, 회원정보 수정 등 |
@RequestBody vs 다른 애노테이션 비교@RequestBody:
POST http://api.example.com/users
Content-Type: application/json
{"name":"홍길동","email":"hong@gmail.com"}
@RequestParam:
GET http://api.example.com/search?keyword=스프링&page=1
@PathVariable:
GET http://api.example.com/users/123
@ModelAttribute:
POST http://example.com/login
Content-Type: application/x-www-form-urlencoded
username=user&password=pass
@RequestBody는 application/x-www-form-urlencoded에서는 동작하지 않음
→ HTML의 <form> 태그 기본 전송 방식과 호환되지 않음
→ 이 경우 400 Bad Request 에러 발생
→ 해결책: @ModelAttribute 사용 또는 JavaScript로 JSON 변환 후 전송
@RequestBody는 multipart/form-data (파일 업로드) 와 호환되지 않음
→ 파일 업로드는 반드시 @RequestParam MultipartFile 사용
→ 또는 DTO 안에 MultipartFile 필드를 두고 @ModelAttribute로 받기
→ 클라이언트의 JSON 구조가 DTO와 맞지 않으면 에러 발생
유효성 검증 방법
→ @Valid 또는 @Validated와 함께 사용
@PostMapping("/api/news")
public ResponseEntity<?> save(@RequestBody @Valid NewsDTO dto, BindingResult result) {
if (result.hasErrors()) {
// 유효성 검증 실패 처리
return ResponseEntity.badRequest().body("유효하지 않은 입력입니다.");
}
// 정상 처리
return ResponseEntity.ok("저장 성공");
}
@RequestBody는 필수 파라미터required=false로 설정하면 요청 바디가 없어도 됨 (Spring 5.1 이상)@PostMapping("/api/optional-body")
public ResponseEntity<?> process(@RequestBody(required=false) InfoDTO info) {
// 요청 바디가 없으면 info는 null
if (info == null) {
return ResponseEntity.ok("요청 바디가 없습니다");
}
return ResponseEntity.ok("처리 완료: " + info.getName());
}