最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kotlin - How can I just get a single field form a nested JSON object with Jackson annotations? - Stack Overflow

programmeradmin2浏览0评论

I get a JSON object like this:

{
    "id": "...",
    "Nested": {
        "nestedId": "..."
    }
}

There are lots of other attributes both in the top level object as in the Nested one.

I'm only interested in a dozen of fields of the top level object, and the Nested object's nestedId.

This code gets them into a Kotlin data class:

import com.fasterxml.jackson.annotation.*

@JsonIgnoreProperties(ignoreUnknown = true)
data class MainObject(
    @JsonProperty("id") val id: String,
    // ... more properties for other fields

    @JsonProperty("nested") val nested: Nested?,
) {
    val nestedId: String? get() = nested?.id
}

@JsonIgnoreProperties(ignoreUnknown = true)
data class Nested(
    @JsonProperty("id") val id: String
)

and I can access the nested object's id nicely with n.nestedId.

I'd still like to get rid off the extra Nested class.

How can I use annotations to only deserialize the nested id instead of the whole object?

I've seen custom a JsonDeserializer, but that seems like it's almost more code and complexity than my little extra class.

I guess I could use readTree and path, but then I'll have to map all the other fields manually.

I get a JSON object like this:

{
    "id": "...",
    "Nested": {
        "nestedId": "..."
    }
}

There are lots of other attributes both in the top level object as in the Nested one.

I'm only interested in a dozen of fields of the top level object, and the Nested object's nestedId.

This code gets them into a Kotlin data class:

import com.fasterxml.jackson.annotation.*

@JsonIgnoreProperties(ignoreUnknown = true)
data class MainObject(
    @JsonProperty("id") val id: String,
    // ... more properties for other fields

    @JsonProperty("nested") val nested: Nested?,
) {
    val nestedId: String? get() = nested?.id
}

@JsonIgnoreProperties(ignoreUnknown = true)
data class Nested(
    @JsonProperty("id") val id: String
)

and I can access the nested object's id nicely with n.nestedId.

I'd still like to get rid off the extra Nested class.

How can I use annotations to only deserialize the nested id instead of the whole object?

I've seen custom a JsonDeserializer, but that seems like it's almost more code and complexity than my little extra class.

I guess I could use readTree and path, but then I'll have to map all the other fields manually.

Share Improve this question asked Feb 7 at 22:06 RobertRobert 8,61853 gold badges116 silver badges159 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Try something like this

@Test
fun `unpack nested field`() {
    val mapper = ObjectMapper().registerKotlinModule()
    val string = """{"id": "main_id", "nested": {"id": "nested_id"}}"""
    val mainObject = mapper.readValue<MainObject>(string)
    assertEquals("nested_id", mainObject.nestedId)
}

data class MainObject(
    val id: String,
    var nestedId: String? = null,
) {
    @JsonProperty("nested")
    private fun unpackNested(nested: Map<String, Any>) {
        this.nestedId = nested["id"] as String
    }
}

In your example nested (inner) field is nullable, but if the nestedId is not nullable, then I would suggest move nestedId out of constructor and make it lateinit:

data class MainObject(
    val id: String
) {
    lateinit var nestedId: String

    @JsonProperty("nested")
    private fun unpackNested(nested: Map<String, Any>) {
        nestedId = nested["id"]!! as String
    }
}
发布评论

评论列表(0)

  1. 暂无评论