Deserialize CSV in Java based on header name

The code is Kotlin, but please read it as you like.

Premise

get along

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

Deserialize CSV in Java based on header name
Read CSV in Java (Super CSV Annotation)
Notes on signal control in Java
Java9 (based on Oracle JVM) catchup
How to name variables in Java
[Java] Returns a Japanese name file in filename of HTTP header
Create a TODO app in Java 7 Create Header
Create a Lambda Container Image based on Java 15
Try scraping about 30 lines in Java (CSV output)
Method name of method chain in Java Builder + α
Upload and download notes in java on S3
Partization in Java
Changes in Java 11
Rock-paper-scissors in Java
I want to return an object in CSV format with multi-line header & filter in Java
Pi in Java
FizzBuzz in Java
Summary for intermediate users based on Java introductory practice
Notes on how to use regular expressions in Java