티스토리 뷰
직렬화 & 역직렬화 Serialization and Deserialization
아래는 스프링 부트 컨트롤러에서 API 를 정의할 때 흔히 볼 수 있는 모습이다:
이 API 를 Swagger 를 사용해서 테스트할 때, 다음과 같이 Request body 부분에 JSON 형태의 정보를 넣어준다.
이렇게 클라이언트로부터 받은 Request body, JSON 정보를 자바 객체 (여기서는 UserLoginRequest) 로 변환하는 과정을 역직렬화 (Deserialization) 라고 부른다.
직렬화 (Serialization) 는 그 반대인 자바 객체를 JSON 형태로 변환하는 과정을 말한다.
역직렬화 시 목적지인 DTO 객체를 생성하여 클라이언트로부터 JSON 형태로 넘어온 데이터를 넣어주는데,
원칙 상으로는 이 과정에서 DTO에 @NoArgsConstructor, 즉 빈 생성자가 있어야만 객체를 정상적으로 생성한다.
그러므로 만약 매개변수를 가진 생성자만 있으면 DTO 를 생성하지 못하고 예외가 발생하는 것이 일반적인 경우이다.
하지만, 프로젝트를 하다보면 분명 @NoArgsConstructor 가 붙어있지 않은데도 정상적으로 작동할 때가 있다.
나의 경우도 아래와 같은 UserLoginRequest 으로도 위 컨트롤러에서 작성한 API 가 정상적으로 작동했다.
알아본 결과, 역직렬화 과정에서 Jackson (JSON 라이브러리) 은 ObjectMapper 를 사용해서 JSON 데이터를 read() 메서드를 사용해서 읽고 특정 방식을 이용해 변환한다. 아래 블로그에 이를 알아내는 과정이 상세하게 설명돼 있으니 참고하자.
Object Mapper 를 사용해서 역직렬화한다는 사실을 알아내는 과정
여기서 특정 방식이 무엇인지 간결하게 설명하고자 이 포스트를 작성하게 되었다.
@NoArgsConstructor 가 있을 때 vs 없을 때
먼저, 디폴트 생성자의 유무에 따라 달라지는 곳이 어디인지 알아보자.
우선, ObjectMapper 에서 사용하는 read() 메서드에서 시작해 차례대로 호출되는 메서드들은 아래와 같다:
이제 deserialize 메서드가 호출된다.
아래의 deserialize() 가 구현된 코드 위의 설명을 보면 bean 객체 (POJO) 를 위한 주요 역직렬화 메서드라고 쓰여있다.
UserLoginRequest 는 빈으로 등록된 POJO 가 맞기 때문에 이 메서드로 역직렬화된다는 것을 이해할 수 있다.
먼저 deserialize 는 다음과 같이 또 차례대로 몇 개의 메서드를 호출한다:
자, 이제 디폴트 생성자의 유무에 따라 달라지는 곳을 발견했다. 아래 코드를 보면, deserializeFromObject() 에서는 if (_nonStandardCreation) 에 따라 다른 메서드를 호출한다.
즉 디폴트 생성자가 없는 "non-standard creation" 상황일 때는 deserializeFromObjectUsingNonDefault() 를,
디폴트 생성자가 있는 "standard creation" 상황일 때는 createUsingDefault() 메서드를 호출한다.
메서드들의 이름에서 유추할 수 있듯, 하나는 빈 생성자를 활용하고, 다른 하나는 무언가 다른 방식을 사용한다.
@NoArgsConstructor 가 없이, @AllArgsConstructor 와 @Getter 만 있을 때
@NoArgsConstructor 가 있을 때
무언가 다른 방식
이 특정 방식에 대한 궁금증이 사실 이 포스트를 작성하게 된 주요 이유이다.
쓰다 보니 길어져 중요성이 가장 높은 글이 마지막에 오게 되어버렸다.
그래서, 이 내용은 다음 포스트에서 이어서 작성하도록 하겠다.
출처
'Java' 카테고리의 다른 글
DTO 의 Deserialize(역직렬화): 3부 (0) | 2022.11.30 |
---|---|
[Java] 원시 타입과 참조형 타입: 배열 생성 방법에서의 차이 (0) | 2022.11.30 |
DTO 의 Deserialize(역직렬화): 2부 (0) | 2022.11.30 |
[Java] enum type Class (0) | 2022.11.18 |
- Total
- Today
- Yesterday
- 실시간데이터
- DTO
- Firebase
- LazyInitializationException
- json web token
- @RequestBody
- 코테
- Jackson
- 지연 로딩
- gitlab
- 깃랩
- 기지국 설치
- Java Data Types
- N+1
- JPQL
- ci/cd
- FCM
- Spring Boot
- JPA
- google cloud
- JOIN FETCH
- DeSerialization
- spring
- 프로그래머스
- docker
- 인증/인가
- 역직렬화
- 가상 서버
- 도커
- 알고리즘
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |