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.
1 Answer
Reset to default 1Try 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
}
}