大多数Jackson插件可以毫无问题地映射到不同或无序的名称,但我很难让jackson-dataformat-csv
执行此操作。它忽略任何@JsonProperty
,而是在编译时根据POJO成员的出现顺序进行填充。如果我先将CSV读取为List<Map<String, String>>
,那么我就可以毫无问题地将其转换为POJO。我是不是错过了一面旗帜?
琐碎的kotlin示例(注意CSV订单有意与POJO订单不同(:
class JacksonCSVTest {
val sampleCsv = """
A,c,BAD_HEADER BAD
1,3,2
""".trimIndent()
class Foo {
@JsonProperty("A")
var a: Int = 0
@JsonProperty("BAD_HEADER BAD")
var b: Int = 0
var c: Int = 0
override fun toString(): String = "Foo(a=$a, b=$b, c=$c)"
}
@Test
fun testDirectReader() {
val csvMapper = CsvMapper()
val schema = csvMapper.schemaFor(Foo::class.java).withHeader()
val foos = csvMapper.readerFor(Foo::class.java).with(schema).readValues<Foo>(sampleCsv).readAll()
val foo = csvMapper.convertValue(foos.single(), Foo::class.java)
println(foo)
}
@Test
fun testMapReader() {
val csvMapper = CsvMapper()
val schema = CsvSchema.emptySchema().withHeader()
val map = csvMapper
.readerFor(HashMap::class.java)
.with(schema)
.readValues<HashMap<String, String>>(sampleCsv)
.readAll()
val foo = csvMapper.convertValue(map.single(), Foo::class.java)
println(foo)
}
}
结果在:
Foo(a=1, b=3, c=2)
> testDirectReader (0.19s)
Foo(a=1, b=2, c=3)
> testMapReader (0.01s)
直接读卡器版本未将列BAD_HEADER BAD
与正确的变量一起放置。地图阅读器版本正确放置了它。
这是怎么回事?
要告诉CsvMapper哪个列是哪个属性,您应该在类的顶部指定@JsonPropertyOrder
注释
kotlin的示例:
@JsonPropertyOrder({ "a", "b" })
data class CsvLine(val a: String, val b: String)
我不知道这个jackson的bug,在解析CSV时也遇到了一些问题。
如果你仍然想这样做,在Jackson的CSV解析器遇到太多问题后,我创建了自己的CSV库Kotlin CSV Stream。。。