@RequestBody, @ResponseBody 어노테이션

박선우·2024년 7월 28일

먼저,

HTTP(HyperText Transfer Protocol) 통신이란,

브라우저와 서버가 통신하기 위한 여러 프로토콜 가운데 한 종류로 웹 브라우저와 웹 서버 사이에 HTML(하이퍼텍스트) 문서를 주고받는 데 사용되는 통신 프로토콜입니다.

HTTP의 통신 방식은 기본적으로 '요청과 응답(request, response)'으로 이루어져 있는데요. 클라이언트가 요청(HttpRequest)을 서버에 보내면 서버는 클라이언트에게 응답(HttpResponse)하는 구조입니다.

HttpRequest 예시는 다음과 같다.

// start line
POST /payment-sync HTTP/1.1

// headers
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 83
Content-Type: application/json
Host: intropython.com
User-Agent: HTTPie/0.9.3

// body (JSON 형식)
{
    "id": "test0101",
    "email": "test0101@gmail.com",
    "address": "google"
}

HttpRequest, HttpResponse 구조

여기서는 위 예시와 같은 HttpRequest와 HttpResponse의 구조에 대해서도 함께 살펴보면 좋은데요.

HttpRequest는 start line, headers, body 세 부분으로 나누어져 있으며, HttpResponse 역시 비슷하게 status line, headers, body 세 부분으로 나누어져 있습니다.

클라이언트와 서버의 비동기 통신 

 클라이언트에서 서버로 통신하는 메시지를 요청(request) 메시지라고 하며, 서버에서 클라이언트로 통신하는 메시지를 응답(response) 메시지라고 한다.
웹에서 화면전환(새로고침) 없이 이루어지는 동작들은 대부분 비동기 통신으로 이루어진다.
비동기통신을 하기위해서는 클라이언트에서 서버로 요청 메세지를 보낼 때, 본문에 데이터를 담아서 보내야 하고, 서버에서 클라이언트로 응답을 보낼때에도 본문에 데이터를 담아서 보내야 한다. 
본문이 바로 body 이다.
즉, 요청본문 requestBody, 응답본문 responseBody 을 담아서 보내야 한다. 

이때 본문에 담기는 데이터 형식은 여러가지 형태가 있겠지만 가장 대표적으로 사용되는 것이 JSON 이다.
즉, 비동기식 클라-서버 통신을 위해 JSON 형식의 데이터를 주고받는 것이다. 

스프링 MVC에서도 클라이언트에서 전송한 xml데이터나 json 등등 데이터를 컨트롤러에서 DOM객체나 자바객체로 변환해서 송수신할 수 있다. 
@RequestBody 어노테이션과 @ResponseBody 어노테이션이 각각 HTTP요청 바디를 자바객체로 변환하고 자바객체를 다시 HTTP 응답 바디로 변환해준다. 

요청 본문(request body)에 담긴 값을 자바객체로 변환.
@RequestBody를 통해서 자바객체로 conversion을 하는데, 이때 HttpMessageConverter를 사용한다. 
@ResponseBody 가 붙은 파라미터에는 HTTP 요청의 분문 body 부분이 그대로 전달된다.
RequestMappingHandlerAdpter 에는 HttpMessageConverter 타입의 메세지 변환기가 여러개 등록되어 있다.

@RequestBody 

@RequestBody 어노테이션은 HttpRequest의 본문 requestBody의 내용을 자바 객체로 매핑하는 역할을 한다.

해당하는 어노테이션이 붙어있는 메서드로 클라이언트의 요청이 들어왔을 때, DispatcherServlet에서는 먼저 해당 HttpRequest의 미디어 타입을 확인하고, 타입에 맞는 MessageConverter를 통해 요청 본문인 requestBody를 통째로 변환해서 메서드로 전달해주게 된다.

이때 주의할 점으로는 일반적인 GET 메서드의 요청 경우에는 HttpRequest의 requestBody로 요청 데이터가 전달되는 것이 아니라, URI 또는 URL의 파라미터로 전달되기 때문에 @RequestBody 어노테이션을 통해 해당 요청 내용을 받을 수가 없다.

GET 메서드의 경우 @PathVariable, @RequestParam 등의 어노테이션을 통해서 요청을 전달받아야 한다.

(GET 메서드에도 body 값을 실어서 요청을 보낼 수 있지만, 설계적인 문제나 클라이언트에서 지원하지 않을 경우가 있을 수 있음)

@ResponseBody 

@ResponseBody 어노테이션은 자바 객체를 HttpResponse의 본문 responseBody의 내용으로 매핑하는 역할을 합니다.

해당 어노테이션 마찬가지로 return Type에 맞는 MessageConverter를 통해 return 하는 객체를 해당 타입으로 변환해서 클라이언트로 전달하게 되는데요.

위 예시 코드를 보면 @ResponseBody가 생략되었는데, 그 이유는 Controller에 붙은 @RestController 때문입니다.

아래 @RestController 어노테이션을 살펴보면 @Controller와 @ResponseBody가 둘 다 붙어있는 것을 볼 수 있는데요.

이처럼 @RestController 어노테이션을 명시했다면 따로 @ResponseBody 어노테이션을 명시하지 않아도 자동으로 HttpResponse의 본문 responseBody에 자바 객체가 매핑되어 전달됩니다.

@RestController

@Controller와는 다르게 @RestController는 리턴값에 자동으로 @ResponseBody가 붙게되어 별도 어노테이션을 명시해주지 않아도 HTTP 응답데이터(body)에 자바 객체가 매핑되어 전달 된다.
@Controller인 경우에 바디를 자바객체로 받기 위해서는 @ResponseBody 어노테이션을 반드시 명시해주어야한다. 

@RequestBody / @ResponseBody 정리. 

클라이언트에서 서버로 필요한 데이터를 요청하기 위해 JSON 데이터를 요청 본문에 담아서 서버로 보내면, 서버에서는 @RequestBody 어노테이션을 사용하여 HTTP 요청 본문에 담긴 값들을 자바객체로 변환시켜, 객체에 저장한다.

서버에서 클라이언트로 응답 데이터를 전송하기 위해 @ResponseBody 어노테이션을 사용하여 자바 객체를 HTTP 응답 본문의 객체로 변환하여 클라이언트로 전송한다. 

참고
https://cheershennah.tistory.com/179
https://wildeveloperetrain.tistory.com/144

profile
개발 관련 궁금한 점이나 새로 알게된 내용을 적는 곳

0개의 댓글