Spring Framework

JsonTypeInfo, JsonSubTypes 어노테이션

Junuuu 2024. 2. 27. 00:01
728x90

개요

이전 글에서 Spring에서 하나의 endpoint에 여러 개의 Request를 받기 위해 @JsonTypeInfo, @JsonSubTypes를 활용해 보았습니다.

@JsonTypeInfo, @JsonSubTypes 어노테이션에 대해 조금 더 자세하게 알아보고자 합니다.

 

@JsonTypeInfo, @JsonSubTypes 왜 사용해야 할까?

interface SingleEndPointRequest {
    val type: String
}

data class DtoA(
        val col1: String,
        val col2: String,
        override val type: String = "DtoA",
): SingleEndPointRequest

data class DtoB(
        val col3: String,
        val col4: String,
        val col5: String,
        override val type: String = "DtoB",
): SingleEndPointRequest

 

추상클래스 혹은 인터페이스의 경우에는 객체 직렬화 역직렬화를 수행할 때 Spring은 어떻게 직렬화를 수행해야 하는지 알 수 없습니다.

즉, SingleEndPointRequest 인터페이스를 DtoA 또는 DtoB로 직렬화하는 것을 Spring이 선택할 수 없습니다.

이 경우에는 @JsonTypeInfo와 @JsonSubTypes를 활용하여 Spring에게 정보를 제공하여 직렬화를 수행할 수 있습니다.

 

 

@JsonTypeInfo, @JsonSubTypes는 무엇인가?

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes(
    JsonSubTypes.Type(value = DtoA::class, name = "DtoA"),
    JsonSubTypes.Type(value = DtoB::class, name = "DtoB")
)
interface SingleEndPointRequest {
    val type: String
}

data class DtoA(
        val col1: String,
        val col2: String,
        override val type: String = "DtoA",
): SingleEndPointRequest

data class DtoB(
        val col3: String,
        val col4: String,
        val col5: String,
        override val type: String = "DtoB",
): SingleEndPointRequest

 

@JsonTypeInfo을 활용하여 직접 클래스의 type 프로퍼티를 보고 결정할 수 있도록 정보를 명시합니다.

@JsonSubTypes를 활용하여 어떤 하위 타입들이 존재하고 type의 값이 name과 일치하는 경우에 value의 클래스로 직렬화를 수행할 수 있도록 명시합니다.

 

SingleEndPointRequest의 type이 DtoA라면 DtoA 클래스로 직렬화가 수행되고, type이 DtoB라면 DtoB 클래스로 직렬화가 수행됩니다.

 

@JsonTypeInfo 어노테이션은 이름에서 알 수 있듯이 Type Info 객체의 클래스 정보를 선언하여 직렬화 및 역직렬화 방법에 대한 세부 사항을 구성하는 데 사용되는 어노테이션입니다.

 

use 필드에 하위 타입의 인스턴스에 대한 추가 정보의 종류와 예상되는 내용을 지정할 수 있습니다.

 

JsonTypeInfo.As.PROPERTY를 사용할 때 객체의 필드 중 속성값과 동일한 필드가 존재하는 경우에 해당 값을 통해 Type을 구분할 수 있습니다.