코딩은 마라톤

Request DTO에서 @Getter를 쓰는 이유 (바인딩) 본문

Backend/SpringBoot

Request DTO에서 @Getter를 쓰는 이유 (바인딩)

anxi 2024. 4. 8. 00:14
이전 게시물에서도 작성했지만 나는 4월 5일 회사 면접을 보았다.
면접 중에 면접관님께서 물으셨다.

면접관님 : request dto에서 @Getter를 쓴 이유가 뭐예요? 프론트에서 request 요청을 서버에서 어떻게 받는지 과정을 알아요?

나 : 음.. Entity 클래스에서 request를 가지고 Entity 객체를 생성하는데 이때 request dto의 필드는 private로 되어있기 때문에 @Getter를 통해 가져오려고 하였습니다 !

면접관님 :  프론트에서 request 요청을 서버에서 어떻게 받는지, @Getter는 왜 사용하는지 공부해보면 좋을 거 같아요.

이렇게 면접관님께서 학습할 부분을 알려주셔서 dto에서 왜 @Getter를 사용하는지, 프론트에서 주는 요청을 어떻게 서버에서 받는지 찾아 보았다.

 

Spring에서의 Binding

바인딩은 사용자 입력 값을 객체의 필드에 매핑하는 과정을 말한다.
즉, 웹페이지에서 입력된 값이 dto를 통해 서버로 넘겨질 때, 바인딩을 통해 dto의 객체로 넘겨진다.

 

스프링 프레임워크에서는 여러 바인딩 기법이 존재한다. 

 

1. @RequestParam

  • 가장 기본적인 방식으로, HTTP 요청의 쿼리 파라미터나 폼 데이터를 받아올 때 사용된다.

2. @RequestBody

  • HTTP 요청의 본문(body) 데이터를 자바 객체로 변환할 때 사용된다.

 따라서 @RequestParam은 쿼리 파라미터나 폼 데이터를 받을 때 사용되고, @RequestBody는 HTTP 요청 본문의 데이터를 자바 객체로 변환할 때 사용된다.

 이때 @RequestBody에서 본문(body) 데이터인 json을 DTO 객체로 변환하는 과정을 "역직렬화(Deserialization)"라고 한다.

 즉, Binding 과정에서 역직렬화를 통해 JSON 데이터를 DTO 객체로 변환하면 서버에서 해당 데이터를 쉽게 다룰 수 있다.

 

 

그렇다면 @Getter를 쓰는 이유는 무엇일까?

@RequestBody

 

@RequestBody는 spring의 HttpMessageConverter를 통해 데이터를 바인딩한다.

 

HttpMessageConverter

HttpMessageConverter 동작 방식

 

request(json) -> dto(object) : 역직렬화, dto(object) -> response(json) : 직렬화 

이 두 과정은 HttpMessageConverter를 이용해 변환된다.

 

동작 과정

1. Dispatcher Servlet에서 해당 요청을 Handler Adapter로 전달한다.

2. Handler Adapter은 ArgumentResolver를 호출하여 요청을 핸들러(컨트롤러)에 전달한다. 이때 Argument Resolver에서 HttpMessageConverter를 사용하여 요청(json)을 객체(dto)로 만든다. <역직렬화>

3. 만들어진 객체를 핸들러(컨트롤러)의 매개면수에 전달하고 핸들러가 동작한다.

4. 만약 핸들러가 반환할 값이 있다면 ReturnValueHandler에서 HttpMessageConverter를 이용해 객체를 응답(json)으로 만들어 반환한다. <직렬화>

 

Argument Resolver는 Spring 환경에서 Controller로 들어온 파라미터를 가공하고나, 수정, 바인딩 기능을 제공할때 사용하는 객체이기 때문에 이 객체를 이용해 핸들러의 매개변수를 객체로 생성하게 된다.

 

https://jenkov.com/tutorials/java-json/jackson-objectmapper.html#how-jackson-objectmapper-matches-json-fields-to-java-fields

 

Jackson 에서는 JSON 필드의 이름을 자바 Object의 getter, setter 메소드를 통해 일치시켜 JSON 필드를 자바 Object필드와 매치시킵니다. 이후 매치된 것을 통해 값을 주입합니다.

 

위 과정을 자세하게 서술한 기술블로그가 있어 첨부합니다 !

https://blogshine.tistory.com/445

 

[Spring] @RequestBody에 기본생성자만 필요하고 Setter는 필요없는 이유 - 1

그간 밀어오고 밀어왔던 내용에 대해 정리하고 넘어가야겠다 싶어 정리하는 글이다. 항상 무의식적으로 Client에게 데이터를 보내거나, 받을 때 일명 DTO를 사용하여 받아왔다. 난 너무나 자연스

blogshine.tistory.com

https://blogshine.tistory.com/446

 

[Spring] @RequestBody에 기본생성자만 필요하고 Setter는 필요없는 이유 - 2

그간 밀어오고 밀어왔던 내용에 대해 정리하고 넘어가야 겠다 싶어 정리하는 글 이다. 지난 글에서 @RequestBody에서 어떤 방식으로 객체를 생성하는 지 파악한 후, 이번 글에서는 객체에 값을 어떤

blogshine.tistory.com

 

결론

  • HttpMessageConverter에서 일어나는 일은 다음과 같다.
    • 요청(JSON) 필드와 객체(DTO) 필드를 매치 - 이때 getter 혹은 setter 메소드 필요(값을 주입할 때가 아닌 필드명을 가져올 때 사용)
    • 요청(JSON) 값을 객체에 주입한다.
  • @RequestBody에서 Binding할 때 ObjectMapper가 생성되는데 기본 생성자로 DTO를 생성하기 때문에 기본 생성자는 일반적인 경우 생성해야한다.
따라서, DTO 객체에는 일반적으로 기본 생성자와 getter만 추가하면 된다.

 

어렵다,, Spring MVC에 대해서 공부를 해본 적이 없기 때문에 Spring MVC 공부를 해야겠다고 생각이 들었다.
또한 매번 dto에 기계적으로 @Getter를 사용했었는데 기본 생성자가 필수적인지 몰랐다.
아마 dto에서 생성자를 추가로 만들지 않았기 때문에 기본 생성자가 컴파일러에 의해 자동으로 생성되서 오류가 없었던 거 같은데 이번 기회를 통해 알 수 있어서 기분 좋다.

'Backend > SpringBoot' 카테고리의 다른 글

[SpringBoot] 서블릿과 서블릿 컨테이너  (0) 2024.06.28
[Springboot] Filter와 Interceptor  (0) 2024.05.08