반응형

build.gradle.kts

dependencies {
    // ...
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
}

ObjectMapper 설정

val objectMapper = jacksonObjectMapper()
    .setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) // snake_case 필드로 직렬화/역직렬화
    .setSerializationInclusion(JsonInclude.Include.NON_NULL)        // null 필드 제외
    .disable(
        DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,      // json에 있는 필드가 object에 없을 경우 발생시키는 오류를 비활성화
    )
    .enable(
        JsonParser.Feature.ALLOW_SINGLE_QUOTES,                 // 필드명을 감싸는 문자로 "뿐만 아니라 '도 허용. ex) {'key': "value"}
        JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES,          // 필드명을 감싸는 문자가 없는 것 허용. ex) {key: "value"}
        JsonParser.Feature.ALLOW_COMMENTS,                      // json 내용에 주석이 포함되어 있는 것 허용.
        JsonReadFeature.ALLOW_TRAILING_COMMA.mappedFeature(),   // 끝에 ,가 붙는 것 허용. ex) {"key": "value",}
    )

객체를 Json으로 변환

val user = User("tyler", 35)
val json = objectMapper.writeValueAsString(user)

Json을 객체로 변환

val json = """{"name":"tyler","age":35}"""
val user = objectMapper.readValue(json, User::class.java)

Json을 Class 타입 객체로 변환

val json = """{"name":"tyler","age":35}"""
val type = Class.forName("com.example.demo.User")
val user = objectMapper.readValue(json, type)

Json을 객체 리스트로 변환

val json = """[{"name":"tyler","age":35}]"""
val type = object : TypeReference<List<User>>() {}
val users = objectMapper.readValue(json, type)

JsonFormat.Shape

@JsonFormat(shape = JsonFormat.Shape.STRING) // default
enum class Status {
    ACTIVE, INACTIVE,
}

val json = objectMapper.writeValueAsString(Status.ACTIVE) // "ACTIVE"
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
enum class Status {
    ACTIVE, INACTIVE,
}

val json = objectMapper.writeValueAsString(Status.ACTIVE) // 0

@JsonProperty

data class User(
    @JsonProperty("USER_NAME")
    val name: String,
    @JsonProperty("USER_AGE")
    val age: Int,
)

val user = User("tyler", 35)
val json = objectMapper.writeValueAsString(user) // {"USER_NAME":"tyler","USER_AGE":35}

@JsonSerializer, @JsonDeserializer

data class User(
    val name: String,
    val age: Int,
    @JsonSerialize(using = TodosSerializer::class)
    @JsonDeserialize(using = TodosDeserializer::class)
    val todos: List<String>,
) {
    class TodosSerializer : JsonSerializer<List<String>>() {
        override fun serialize(value: List<String>, gen: JsonGenerator, serializers: SerializerProvider) {
            gen.writeString(value.joinToString(","))
        }
    }

    class TodosDeserializer : JsonDeserializer<List<String>>() {
        override fun deserialize(p: JsonParser, ctxt: DeserializationContext): List<String> {
            val node = p.codec.readTree<JsonNode>(p)
            return node.asText().split(",")
        }
    }
}

val json = """{"name":"tyler","age":35,"todos":"A,B"}"""
val user = objectMapper.readValue(json, User::class.java)

타입 추론을 통한 객체 파싱

data class User(
    val name: String,
    val age: Int,
)

val objectMapper = jacksonObjectMapper()
    // ...
    .setDefaultTyping(
        StdTypeResolverBuilder()
            .init(JsonTypeInfo.Id.CLASS, null) // 클래스패스 기반으로 타입을 구분
            .inclusion(JsonTypeInfo.As.PROPERTY)     // @class 필드값으로 타입을 추론
            .typeProperty("@class")    // @class 라는 필드명에 클래스패스 값을 저장
    )

val user = User("tyler", 35)
val json = objectMapper.writeValueAsString(user)
val result = objectMapper.readValue(json, Any::class.java) // User 타입으로 파싱
반응형

'Development > Kotlin' 카테고리의 다른 글

[Kotlin] Coroutine  (0) 2024.02.17
[Kotlin] Kotlin 소스 파일 컴파일하여 Class 객체로 로딩하기  (0) 2023.05.27
[Kotlin] 기본 문법  (0) 2020.12.28

+ Recent posts