스프링을 이용해서 rest api를 구성할 때 클라이언트와 데이터를 JSON 형태로 통신하기위해 사용하는 어노테이션이 @ResponseBody
, @RequestBody
입니다.
TestDto.java
@Getter
public class TestDto {
private String a;
private String b;
@Builder
public TestDto(String a, String b) {
this.a = a;
this.b = b;
}
}
TestController.java
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping
public ResponseEntity<TestDto> testGet() {
TestDto testDto = TestDto.builder()
.a("테스트 a")
.b("테스트 b")
.build();
return ResponseEntity.ok(testDto);
}
@PostMapping
public ResponseEntity<TestDto> testPost(@RequestBody TestDto testDto) {
return ResponseEntity.ok(testDto);
}
}
스프링 4.x 버전부터 지원하는 @RestController
는 @Controller
와 @ResponseBody
가 결합된 어노테이션입니다.
@RestController
를 붙이면 클래스 하위 메서드들에 따로 @ResponseBody
를 붙이지 않아도 JSON형태의 데이터를 전송할 수 있습니다.
Controller가 잘되는지 확인한 결과는 아래와 같습니다.
$ curl 'http://localhost:8080/test' -i -X GET
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 31 Aug 2022 17:07:37 GMT
{"a":"테스트 a","b":"테스트 b"}
$ curl 'http://localhost:8080/test' -i -X POST \
-H 'Content-Type: application/json' \
-d '{"a" : "테스트", "b" : "테스트"}'
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 31 Aug 2022 17:10:08 GMT
{"a":"테스트","b":"테스트"}
GET요청으로 객체를 JSON형태로 변환이 성공됬으며 POST요청으로 보낸 body가 TestDTO에 매핑된 것을 확인할 수 있습니다.
여기서 의문인 점은 Spring에서는 어떻게 객체와 JSON이 서로 변환될 수 있을까요?
바로 @ResponseBody
, @RequestBody
어노테이션을 명시해서 MessageConverter
를 통한 데이터 변환(직렬화, 역직렬화)과정을 거칩니다.
spring-web 라이브러리에서는 HttpMessageConverter
를 상속받은 다양한 Converter가 존재합니다.
요청 또는 응답에 존재하는 데이터 유형에 따라 서로 다른 MessageConverter
가 사용되며
Rest Api의 요청, 응답에서 가장 많이 쓰이는 객체 같은 경우는 MappingJackson2HttpMessageConverter
가 사용됩니다.
@ResponseBody
, @RequestBody
가 명시된 메서드가 호출 된다면 직렬화 또는 역직렬화에 맞는 MappingJackson2HttpMessageConverter
하위 메서드들이 실행되고 내부에 존재하는 ObjectMapper
를 이용하여 JSON 또는 객체 형태로 컨버팅됩니다.
객체, JSON이 서로 어떻게 컨버팅하는지 궁금했는데 브레이크포인트를 걸어보면서 이해를 조금이나마 하게됬습니다.
틀린 부분이 있으면 댓글로 적어주세요! 읽어주셔서 감사합니다.