[@RequsetBody] @RequestBody와 생성자

2021. 9. 11. 03:39개발공부/Spring

@RequestBody와 생성자

결론부터 얘기하자면 @RequestBody는 기본 생성자가 필요합니다. @Builder + (@NoArgsConstructor, @AllArgsConstructor) 같이 쓰는 것과
마찬가지죠.

결론을 봤으니 이해를 위해 원리를 알아야 됩니다. 그러기 위해 Serialize 직렬화, Deserialize 역직렬화를 알아야 합니다.
직렬화는 JSON과 관련이 있는데요, Java Object를 JSON으로 파싱해주는 과정을 직렬화라고 부릅니다. 역직렬화라는 용어는 잘 쓰진 않지만
JSON을 Object로 변환하는 것입니다. @RequestBody가 자동으로 처리해주기 때문이죠.

Jackson의 ObjectMapper 클래스가 readValue()라는 메서드로 역직렬화를 해주는데 내부 메서드를 살펴보면 기본 생성자가 null 일 때와
그렇지 않을 때 처리가 달라지는데 기본 생성자가 없을 경우 생성자 위임이 있는지, @JsonProperty, @JsonAutoDetect를 사용한
Property 기반 클래스가 아니라면 오류가 발생합니다.

공식문서를 봤더니 파라미터에 @RequestBody가 있으면 HttpMessageConverter를 통해 HTTP body를 매핑해준다고 합니다.
HttpMessageConverter는 HTTP request message를 역직렬화(Object로 파싱) 해주는 역할을 합니다.

다른 블로그에서 찾은건데 Object 멤버변수가 오직 하나일 경우(==생성자 인자가 하나일 경우) @JsonCreator로 Object를 자동설정해줘
getter/setter/기본생성자가 없이 처리해주는 Jackson이 제 역할을 하지 않는다고 합니다...두둥

정리하자면 HttpMessageConverter가 역직렬화를 할 때 Jackson은 Obejct를 @JsonCreator로 사용자가 getter/setter/기본생성자를
설정하지 않아도 바인딩이 될 수 있도록 도와줍니다. 하지만 생성자 인자가 하나일 땐 지원하지 않는다는 점, 꼭 참고해야합니다.


참고자료:

개인블로그 - @RequestBody에 왜 기본 생성자는 기본이고...

개인블로그 - @RequestBody 모델에 기본생성자..

스프링 공식문서 - mapping the request body with the @RequestBody

API문서 - JsonCreator