티스토리 뷰
❖ 사용안
계층구조에서 다른 하위클래스를 여러개 가지고 있을 경우 이를 처리하기 위해서 사용합니다.
예를 들어 동물 하위에 강아지, 고양이, 토끼라는 하위 클래스가 있고 이들이 가지고 있는 필드와 처리하는 함수가 다를 경우 이를 하나의 필드로 구분하여 사용할 수 있습니다.
❖ 어노테이션 설명
@JsonTypeInfo : 다형성을 지원하는 Jackson 라이브러리로 json 직렬, 역직렬을 지원합니다.
- use : 다형성을 나타내는 정보를 어떻게 사용할지 지정합니다.
- JsonTypeInfo.Id.NAME : 타입 이름을 사용하여 다형성을 처리합니다.
- JsonTypeInfo.Id.CLASS: 클래스 정보를 사용하여 다형성을 처리합니다.
- JsonTypeInfo.Id.MINIMAL_CLASS: 최소한의 클래스 정보만 사용하여 다형성을 처리합니다. 클래스 이름을 속성으로 포함시킵니다.
- JsonTypeInfo.Id.NONE: 다형성 정보를 사용하지 않습니다. - include : 다형성 정보를 어떤 방식으로 포함할지 지정
- JsonTypeInfo.As.PROPERTY: 다형성 정보를 JSON 속성으로 포함시킵니다.
- JsonTypeInfo.As.EXISTING_PROPERTY: 기존의 JSON 속성을 사용하여 다형성 정보를 포함시킵니다.
- JsonTypeInfo.As.WRAPPER_OBJECT: 다형성 정보를 JSON 객체로 감싸서 포함시킵니다.
- JsonTypeInfo.As.WRAPPER_ARRAY: 다형성 정보를 JSON 배열로 감싸서 포함시킵니다.
- JsonTypeInfo.As.EXTERNAL_PROPERTY: 외부 속성에 다형성 정보를 포함시킵니다. - property : 다형성 정보를 포함할 JSON 속성의 이름을 지정합니다.
- visible : 다형성 정보가 JSON에 노출되어야 하는지 여부를 지정합니다.(기본값은 true)
@JsonSubTypes : 다형성의 서브타입을 지정
- value : 매핑할 하위 클래스를 지정합니다.
- name : 해당 하위 클래스에 대한 이름을 지정합니다.
❖ 예제
objectMapper를 통해 snake_case로 정의할 수 있습니다.
이때 JsonTypeInfo.property 도 skake_case로 정의되어야 합니다.
보통 프론트와 통신시 json필드를 snake_case로 규칙을 정의하므로 해당 옵션을 추가하였습니다.
import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.PropertyNamingStrategies
import com.fasterxml.jackson.module.kotlin.KotlinModule
import net.suby.kotlin.json.subtype.AnimalType.CAT
import net.suby.kotlin.json.subtype.AnimalType.DOG
import net.suby.kotlin.json.subtype.AnimalType.RABBIT
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "animal_type")
@JsonSubTypes(
JsonSubTypes.Type(value = Dog::class, name = "DOG"),
JsonSubTypes.Type(value = Cat::class, name = "CAT"),
JsonSubTypes.Type(value = Rabbit::class, name = "RABBIT"),
)
sealed class Animal(
val animalType: AnimalType,
open val name: String,
)
data class Dog(
override val name: String,
val color: String,
) : Animal(DOG, name)
data class Cat(
override val name: String,
val howling: String,
) : Animal(CAT, name)
data class Rabbit(
override val name: String,
val numberOfLegs: Int,
) : Animal(RABBIT, name)
data class AnimalHospital(
val name: String,
val animal: Animal,
) {
val dog: Dog
get() = animal as Dog
val cat: Cat
get() = animal as Cat
val rabbit: Rabbit
get() = animal as Rabbit
}
fun main() {
val objectMapper = ObjectMapper()
.registerModule(KotlinModule.Builder().build())
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) // snake_case로 변환
val dog = Dog("멍뭉이", "흰색")
val cat = Cat("냥옹이", "야옹")
val rabbit = Rabbit("토순이", 4)
// Serialize dog to JSON
val dogJson = objectMapper.writeValueAsString(dog)
println(dogJson)
val catJson = objectMapper.writeValueAsString(cat)
println(catJson)
val rabbitJson = objectMapper.writeValueAsString(rabbit)
println(rabbitJson)
// Deserialize JSON to animal object
val deserializedDog = objectMapper.readValue(dogJson, Animal::class.java)
val deserializedCastDog = deserializedDog as Dog
val deserializedCat = objectMapper.readValue(catJson, Animal::class.java)
val deserializedCastCat = deserializedCat as Cat
val deserializedRabbit = objectMapper.readValue(rabbitJson, Animal::class.java)
val deserializedCastRabbit = deserializedRabbit as Rabbit
println(deserializedDog)
println(deserializedCastDog)
println(deserializedCat)
println(deserializedCastCat)
println(deserializedRabbit)
println(deserializedCastRabbit)
val dogHospital = AnimalHospital("강아지 병원", dog)
val catHospital = AnimalHospital("고양이 병원", cat)
val rabbitHospital = AnimalHospital("토끼 병원", rabbit)
val animalHospitals = listOf(dogHospital, catHospital, rabbitHospital)
val firstAnimalHospital = animalHospitals[0].dog
println(firstAnimalHospital.animalType)
println(firstAnimalHospital.color)
}
실행 결과
{"name":"멍뭉이","color":"흰색","animal_type":"DOG"}
{"name":"냥옹이","howling":"야옹","animal_type":"CAT"}
{"name":"토순이","number_of_legs":4,"animal_type":"RABBIT"}
Dog(name=멍뭉이, color=흰색)
Dog(name=멍뭉이, color=흰색)
Cat(name=냥옹이, howling=야옹)
Cat(name=냥옹이, howling=야옹)
Rabbit(name=토순이, numberOfLegs=4)
Rabbit(name=토순이, numberOfLegs=4)
DOG
흰색
'라이브러리' 카테고리의 다른 글
[kotlin]redis의 orm 라이브러리 (0) | 2023.07.02 |
---|---|
kotlin + rest docs + swagger 문서 자동화 (0) | 2023.02.10 |
resilience4j springboot2 설명 및 구현 (0) | 2022.09.14 |
queryDsl 를 통한 counting 구하기 (0) | 2022.07.04 |
KeyGenerator을 활용한 Spring Cache key 생성하기 (0) | 2022.06.15 |
댓글
공지사항