The code is Kotlin, but please read it as you like.
You can do this with jackson-dataformat-csv. https://github.com/FasterXML/jackson-dataformats-text/tree/master/csv
The documentation is pretty fluffy and esoteric, but you can do it.
import assertk.assert
import assertk.assertions.isEqualTo
import assertk.assertions.isNotNull
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonUnwrapped
import com.fasterxml.jackson.dataformat.csv.CsvMapper
import com.fasterxml.jackson.dataformat.csv.CsvSchema
import org.junit.Test
class DeserializeTest {
enum class Country {
JP,
US
}
class Profile {
@JsonProperty("age")
val age: Int = 0
@JsonProperty("country")
val country: Country = Country.JP
}
class User {
@JsonProperty("_id")
val id: Int = 0
@JsonProperty("name")
val name: String = ""
@JsonUnwrapped(prefix = "profile.")
val profile: Profile? = null
}
@Test
fun deserialize() {
val mapper = CsvMapper()
val schema = CsvSchema.emptySchema().withHeader()
val reader = mapper.readerFor(User::class.java).with(schema)
val users = reader.readValues<User>("""
name,_id,profile.age,profile.country
foo,3,17,JP
bar,2,21,US
""".trim()).readAll()
assert(users[0].id).isEqualTo(3)
assert(users[0].name).isEqualTo("foo")
assert(users[0].profile).isNotNull {
assert(it.actual.age).isEqualTo(17)
assert(it.actual.country).isEqualTo(Country.JP)
}
assert(users[1].id).isEqualTo(2)
assert(users[1].name).isEqualTo("bar")
assert(users[1].profile).isNotNull {
assert(it.actual.age).isEqualTo(21)
assert(it.actual.country).isEqualTo(Country.US)
}
}
}
The point is not to give type information to CsvSchema.
If you pass the type information here, it will only be deserialized based on the column order.
@JsonUnwrapped
is sober and amazing. Convenient.
JavaBeans are required, so if you're writing in Kotlin, give up on non-null. It's sad, is not it.
Recommended Posts