Java/Spring

[Spring] Json 직렬화, 역직렬화

SeungbeomKim 2024. 12. 24. 18:25

개발 중 Lazy Loading 된 객체에서 해당 소스코드가 존재했습니다.

public String getRegionName() {
    return region == null ? null : region.getName();
}

 

Intellij에서 no usage로 해당 메서드를 사용하는 클래스가 존재하지 않았지만, 해당 정보를 가져올 수 있었습니다. 그 이유는 Json 직렬화, 역직렬화의 내부적인 동작과정 때문인데요. Json 직렬화, 역직렬화에 대해 알아보고 정리해 보도록 하겠습니다. 

 

기본적으로 Spring Application을 구동하기 위한 의존성인 spring-boot-starter-web에 Json 직렬화 및 역직렬화를 할 수 있는 라이브러리가 내장되어 있습니다. (Jackson Library)

 

직렬화, 역직렬화의 개념에 대해 정리해보겠습니다.

  1. 직렬화: 외부의 시스템에서 사용할 수 있도록 바이트 형태로 데이터를 변환하는 기술 (Object → Json)
  2. 역직렬화: 외부 시스템의 바이트 형태의 데이터(Json)를 객체나 해시 테이블, 딕셔너리 등으로 변환하는 것을 의미 (Json → Object)

https://www.linkedin.com/pulse/d365fo-json-serialization-deserialization-wajahat-wasti/

 

 

Spring에서는 Jackson Library의 ObjectMapper 클래스를 통해 위 과정들이 발생하는데요. 어떻게 발생하는지 간단히 정리해 보겠습니다.

 

직렬화 (object → json)

  • ObjectMapper의 writeValue 메서드를 통해 직렬화합니다.
  • getter, setter 필요합니다.
  • 내부적으로 getXXX, setXXX 형태의 메서드를 찾아, json의 key를 할당합니다.

 

역직렬화 (json → object)

  • ObjectMapper의 readValue 메서드를 통해 json을 object로 역직렬화합니다.
  • @RequestBody를 통해 readValue() 메서드를 수행합니다.
  • 기본생성자, Getter, Setter가 필요합니다.
  • ObjectMapper는 Reflection 기술을 이용해 기본생성자와 Getter, Setter를 참고합니다.

 

즉, 위의 regionName을 호출하는 메서드는 Jackson과 같은 직렬화 라이브러리가 Entity를 Json으로 변환할 때 호출하게 됩니다. 해당 필드를 필요한 경우에만 사용하기 위함과 성능을 고려한 코드라고도 볼 수 있습니다. (불필요한 쿼리 방지)

 

추가로 역직렬화 과정에서 예외 상황이 있습니다. 바로 DTO에서 기본생성자가 없는대도 역직렬화가 가능한 경우입니다. 

 

기본생성자가 없는대도 역직렬화가 가능한 경우

  • com.fasterxml.jackson.module:jackson-module-parameter-names 에 존재하는 ParameterNamesModule 클래스의 동작에 의해 가능하게 됩니다.
  • 해당 클래스가 JsonCreater를 사용해 기본생성자가 없는 객체도 역직렬화를 가능하게 합니다.
  • @RequestBody annotation이 적용된 클래스에만 해당이 됩니다.