데이터 매핑 - 직렬화, 역직렬화 (with JSON)

달래·2023년 11월 12일
0

Spring

목록 보기
2/7

여태까지 Request Dto를 만들면서,무지성으로 @Data, @AllArgsConstructor, @NoArgsConstructor를 사용해오곤 했다.

그런데 개인 프로젝트를 진행하다보니 front에서 데이터를 보내는 방식마다 어떻게 Dto에 값이 매핑되고 Repsonse되는지 몰라서 헤매게 되더라..(무지성 코딩의 폐해)

이 참에 Dto에서 어떻게 데이터가 바인딩되는지 알아보기로 했다!

직렬화/역직렬화?

보통 웹 request를 보낼 때, 어떻게 데이터를 보낼까?


크게 http parameter(?id=1&pwd=123와 같은 쿼리스트링)으로 보내는 경우와,
http body 중 JSON 또는 form-data로 보내는 경우가 있다.

우리는 이렇게 request로 받은 데이터를 가공하거나 사용하기 위해서,
Dto클래스와 같이 Java 객체로 매핑하는 과정이 필요하다.

여기에서 request 데이터 → Java 객체(Dto)로 만드는 과정을 역직렬화라고 하고,
Java 객체(Dto) → response 데이터(Json)로 만드는 과정을 직렬화라고 한다.


Http Body (JSON)

Http Body의 Message를 읽기 위해서 스프링은 Http Message Converter에서 Jackson을 사용한다.


역직렬화(Json → Java객체)는 ObjectMapper를 사용하는데, Jackson Converter도 이와 같이 ObjectMapper를 사용한다.


ObjectMapper의 Dto 직렬화/역직렬화 과정은 다음과 같다.
(Dto클래스의 모든 필드의 접근제한자는 private/protected를 가정한다)

1. 역직렬화 (Json → Dto)

@Getter
public class RequestDto {
	private String id;
    private String pwd;
}
  • 역직렬화는 getter를 통해서 json데이터의 key와 매핑한다.
  • 더 자세히 말하자면, getter의 return값으로 매핑한다.
  • getter가 없다면 406 Not Accpetable가 리턴된다!

2. 직렬화 (Dto → Json)

@Getter
@Setter 또는 @AllArgsConstructor
public class ResponseDto {
	private String id;
    private String pwd;
}
  • 위에서 언급했듯이 역직렬화는 getter를 통해서,
    직렬화는 setter를 통해서 json데이터의 key와 매핑한다.
  • setter를 지양하는 경우는 @AllArgsConstructor를 사용해도 무방하다.


번외) @ModelAttribute의 경우

Json타입이 아닌 데이터를 reuqest데이터로 받았다면 어떻게 할까?


쿼리스트링인 Http Parameter를 받거나,
form-data인 Http Body를 받는 경우, 우리는 @ModelAttribute를 통해 Dto를 바인딩 할 수 있다.

역직렬화&직렬화

@Getter
@Setter 또는 @AllArgsConstructor
public class RequestDto {
	private String id;
    private String pwd;
}

@ModelAttributesetter나 모든생성자를 통해서 데이터를 바인딩한다.
따라서, getter만 있다면 객체의 값이 바인딩되지 않는다.
기본형 타입의 필드는 null이, 참조형 타입의 필드는 0와 같은 초기값이 바인딩된다.

나의 생각으로는 Json타입의 데이터의 경우 역직렬화와 직렬화 과정을 나누어 Repsonse할 필요가 있지만, @ModelAttribute의 경우 이 과정이 함께 일어나면서 데이터가 매핑됨과 동시에 바인딩하기 때문에 setter(또는 모든 생성자)의 선언이 필요한 것 같다.



결론

  • 역직렬화, 즉 json데이터를 받아 Dto로 변환할 때에는 getter를 통해 데이터를 바인딩한다.
  • 직렬화, 즉 비즈니스로직을 처리한 후 json으로 응답할 때에는, setter나 모든 생성자를 통해 데이터를 바인딩한다.
  • parameter나 form-data의 경우, @ModelAttribute사용해 getter, setter(또는 모든생성자)를 통해 데이터를 바인딩할 수 있다.
profile
아좌잣~!

0개의 댓글