본문 바로가기
카테고리 없음

RequstBody / ResponseBody

by asdft 2024. 1. 16.

@RequestBody @ModelAttribute는 클라이언트 측에서 보낸 값을 오브젝트 형태로 매핑해줘서 사용할 수 있도록 제공하는 공통점이 있다.
하지만, 두 에노테이션은 큰 차이가 있기 때문에 특징 및 차이점에 대해서 살펴보자.


1. RequstBody

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

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

 

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

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

 

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

 

@ModelAttribute와 값을 바인딩한다는 관점에서는 동일하지만, 이는 HTTP Message Body(요청 본문)를 읽는 다는점에서 다릅니다.

Json 또는 XML를 HttpMessageConverter를 통해 파싱되어 객체로 변환

@RequestBody 내부 코드를 살펴보면, 여러 MessageConverter 중 MappingJackson2HttpMessageConverter를 사용함을 확인할 수 있다.

메서드를 타고 들어가다 보면 내부적으로 ObjectMapper를 통해 Json 값을 자바 객체로 역직렬화 하는 것을 알 수 있다.

역직렬화란 리플렉션을 통해 객체를 구성하는 매커니즘이며, 리플렉션은 무조건 기본 생성자가 필요하다.

Spring Data JPA 에서 Entity에서 기본 생성자가 필요한 이유도 동적으로 객체 생성 시 리플렉션을 활용하기 때문이다.

따라서, @RequestBody에 사용하려는 dto가 기본 생성자를 정의하지 않으면 데이터 바인딩에 실패한다.

 

 

 

 

 

그렇다면 post가 생성된 이후에 어떻게 해야할까?

그저 생성하는 것에서 끝나는 것이 아니라 /posts/{id} 에 대한 필드를 만들어 생성된 유저 정보를 확인 할 수 있게 만들었다.

이러한 URI Location 에 대한 설정은 다음과 같이 처리한다

  • ServletUriComponentBuilder.fromCurrentRequest 를 통하여 현재 요청된 uri 를 받아온다
  • 이후 path 를 추가하여 id 를 variable로 설정
  • buildAndExpand 를 통하여 variable 을 id 와 매핑한다
  • 만들어진 uri 를 통하여 ResponseEntity 를 빌드

java.lang.Object org.springframework.web.util.UriComponentsBuilderorg.springframework.web.servlet.support.ServletUriComponentsBuilder

RequestContextHolder란?

RequestContextHolder란?

Spring 2.x부터 제공되던 기능으로 Spring 전역으로 Request에 대한 정보를 가져오고자 할 때 사용하는 유틸성 클래스입니다. 주로 Controller가 아닌, Service에서 Request 객체를 참고하려 할 때 사용합니다.

 

 

참고

https://wonyong-jang.github.io/spring/2020/06/07/Spring-ModelAttribute-RequestBody.html