Search

@RequestBody와 @ModelAttribute의 차이

Tags
@RequestBody
@ModelAttribute
Date
2023/09/16

개요

@RequestBody와 @ModelAttribute 모두 요청으로 부터 받은 데이터를 Java 객체로 변환할 때 사용하는 어노테이션입니다. 하지만 이 둘은 분명한 차이점을 갖고 있는데요, 이번 포스팅에서는 두 어노테이션의 특징과 차이점에 대해 알아보도록 하겠습니다.

1.결론부터

결론부터 빠르게 말하자면 클라이언트가 전송하는 데이터의 형태에 따라 둘의 쓰임새가 다릅니다.
@RequestBody 의 경우 application/json 형태의 데이터를 Java 객체로 변환 시켜주는 역할을 하고, @ModelAttribute의 경우 form 형태의 데이터 혹은 파라미터 들을 Setter로 바인딩하기 위해 사용됩니다.

2. @RequestBody란

@RequestBodyHttpMessageConverter를 통해 요청 타입에 맞는 Java 객체로 변환됩니다. 내부적으로 더 파헤쳐보면 ObjectMapper를 통해 자바 객체로 변환되는 것을 알 수 있는데요, 이를 위해 기본 생성자와 @Getter 혹은 @Setter를 적어도 하나 이상 선언해주어야 합니다.
다음과 같이 컨트롤러와 도메인 객체가 존재한다고 가정해봅시다.
@RestController public class ExampleController { @PostMapping("/example") public String postExample(@RequestBody Person person) { return "Received: " + person.getName() + " who is " + person.getAge() + " years old."; } }
Java
복사
public class Person { private String name; private int age; // getters and setters public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Java
복사
만약 아래와 같은 JSON 요청을 전송하면 다음과 같은 결과가 나옵니다.
{ "name": "John", "age": 30 } Received: John who is 30 years old.
Java
복사
반대로 JSON 형식으로 데이터를 전송하는데 @ModelAttribute로 이를 변환하려고 하면 예외가 발생합니다.

2. @ModelAttribute란

@ModelAttribute 어노테이션은 클라이언트가 전송한 여러 파라미터를 하나의 객체에 바인딩하는 데 사용됩니다. 주로 폼 제출과 같은 경우에 사용되며, 요청 파라미터를 URL에 첨부하거나 application/x-www-form-urlencodedmultipart/form-data 형식으로 데이터를 전송할 때 사용됩니다.
이 어노테이션을 사용하여 JSON 본문을 수신하려고 하면, 스프링이 기대하는 방식으로 데이터가 구성되지 않았기 때문에 에러가 발생합니다. JSON 형식의 데이터를 받으려면 @RequestBody를 사용해야 합니다.
@ModelAttribute가 받을 수 있는 데이터 형식은 다음과 같습니다.
1. URL 쿼리 파라미터
URL에 직접 파라미터를 첨부하여 GET 요청을 보낼 수 있습니다. 예를 들어:
GET /example?name=John&age=30
Plain Text
복사
2. 폼 데이터 (POST 요청)
HTML 폼을 사용하여 POST 요청을 보낼 수 있습니다. 이 경우 application/x-www-form-urlencoded 또는 multipart/form-data 형식을 사용합니다.
HTML 폼 예시:
<form action="/example" method="post"> <label for="name">Name:</label> <input type="text" id="name" name="name"> <label for="age">Age:</label> <input type="text" id="age" name="age"> <input type="submit" value="Submit"> </form>
HTML
복사
또는, CURL을 사용하여 명령줄에서 POST 요청을 보낼 수도 있습니다:
curl -X POST -d "name=John&age=30" http://localhost:8080/example
Plain Text
복사
컨트롤러 또한 다음과 같이 수정해주어야 합니다.
@RestController public class ExampleController { @PostMapping("/example") public String postExample(@ModelAttribute Person person) { return "Received: " + person.getName() + " who is " + person.getAge() + " years old."; } }
Java
복사