[spring] 응답 필드 동적 추가 (Serialization)

GuruneLee·2023년 1월 1일
0

Let's Study 공부해요~

목록 보기
33/36
post-thumbnail

문제

API 서버 개발 중, '생년월일'를 쿼리해와서 응답객체엔 '생년월일'과 '만 나이' 모두를 담아야 하는 요구사항이 있었다.

처음엔 다음과 같이 Response 클래스에 age 필드를 추가하고, birthDate 를 age 로 직접 바꿔서 필드에 값을 넣어줫다

// age 필드 직접 추가
// Response.kt
class Response(
    val birthDate: LocalDate,
) {
    val age: Int = birthDate.toAge() //확장함수 toAge()
}

그런데, 다른 개발자분이 만들어 놓으신BirthDate 클래스, BirthDateSerializer 클래스를 발견해서 해당 클래스에 대해 알아보고 사용하고자 한다

코드

먼저 BirthDateBirthDateSerializer를 보자

// BirthDate
@JsonSerialize(
    using = BirthDateSerializer::class,
)
data class BirthDate(
    val value: LocalDate?,
    val formatter: DateTimeFormatter = DateTimeFormatter.ISO_DATE
)
  • LocalDate 값과 Format 을 갖는다
  • @JsonSerialize 어노테이션이 선언되어 있다
    • Jackson 에 포함된 어노테이션
    • 해당 entity를 직렬화할 때 사용할 커스텀 Serializer를 사용할 수 있게 한다
    • 이를 붙이지 않으면, Jackson 미리 정의된 대로 직렬화가 된다.
      (RestController에서 직렬화될테니 아마 'JsonSerializer'가 기본으로 쓰일 듯)
  • 직접 정의한 BirthDateSerializer 를 사용한다고 명시해두었다.
// BirthDateSerializer
@Component
class BirthDateSerializer(private val generatorService: GeneratorService): JsonSerializer<BirthDate>() {
    override fun serialize(birthDate: BirthDate, generator: JsonGenerator, provider: SerializerProvider) {
        generator.writeString(birthDate.value?.format(birthDate.formatter))
        when (val resolveAge = resolveAge(birthDate, RequestContextHolder.getZoneId())) {
            null -> generator.writeStringField("age", null)
            else -> generator.writeNumberField("age", resolveAge)
        }
    }
 
    fun resolveAge(birthDate: BirthDate, zoneId: ZoneId): Short? {
        // ...
    }
}
  • JsonSerializer<> 를 상속받아 serialize를 구현한 모습
  • serialize 메서드에서 BirthDate를 받아와서 generatorwriteXXX메서드를 이용해 birthDateage를 넣는 모습
  • 이걸 컴포넌트로 등록해두면 (@Component) @JsonSerializer 에 등록해서 사용 가능

(추가) 직렬화

Serialization (직렬화)
: 객체를 데이터스트림(ex. 바이트 스트림)으로 만드는 것. 네트워크 전송 등, 데이터를 이동시켜야 할 때 필요하다.
( ex. 세션 객체를 저장할 때 외부 스토리지 등 네트워크 자원을 사용해야 저장할 수 있는 상황이면, 직렬화를 반드시 해야함)

직렬화엔 여러 포맷이 존재하는데, 표 형태의 다량 데이터를 직렬화 할땐 CSV / 단일 객체 기반 구조적 데이터는 XML, JSON 으로 직렬화할 수 있다.

라고만 하면 처음엔 이해할 수 없다.
다음 글을 읽어보면 감이 온다.

TL;DR
직렬화 = Reference 값이 가르키는 실제 값을 모두 긁어와 Primitive 값으로 변조하는 작업

블로그: https://ahma.tistory.com/65 (아래쪽 '댓글'본문을 확인하자)

profile
Today, I Shoveled AGAIN....

0개의 댓글