kotlinとjacksonを用いてファーストクラスコレクションパターンを記載する
0.想定する仮想class
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.+")
sample.kt
data class TaskList(
val items: List<Task>
)
data class Task(
val taskId: String,
val title: String
)
上記のままserialize処理を実施すると、ファーストクラスコレクションに記載されたargumentまで、serialize処理されてしまう。
result.json
{"items":[{"taskId":"taskId","title":"title"}]}
1. serializerをoverrideする
part1.kt
@JsonSerialize(using = TaskListSerializer::class)
data class TaskList(
val items: List<Task>
)
private class TaskListSerializer: JsonSerializer<TaskList>() {
override fun serialize(value: TaskList, gen: JsonGenerator, provider: SerializerProvider) {
gen.writeStartArray()
value.items.forEach { gen.writeObject(it) }
gen.writeEndArray()
}
}
result.json
[{"taskId":"taskId","title":"title"}]
2. DeSerializerをoverrideする
地味ではあるが、List型はArrayにしてファーストクラスコレクションに入れる際に、list化する
part2.kt
@JsonSerialize(using = TaskListSerializer::class)
@JsonDeserialize(using = TaskListDeSerializer::class)
data class TaskList(
val items: List<Task>
)
private class TaskListSerializer: JsonSerializer<TaskList>() {
override fun serialize(value: TaskList, gen: JsonGenerator, provider: SerializerProvider) {
gen.writeStartArray()
value.items.forEach { gen.writeObject(it) }
gen.writeEndArray()
}
}
private class TaskListDeSerializer : JsonDeserializer<TaskList>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): TaskList {
val taskArray = p.readValueAs(Array<Task>::class.java)
return TaskList(taskArray.toList())
}
}
3. 全体概要
sample.kt
@JsonSerialize(using = TaskListSerializer::class)
@JsonDeserialize(using = TaskListDeSerializer::class)
data class TaskList(
val items: List<Task>
)
data class Task(
val taskId: String,
val title: String
)
private class TaskListSerializer: JsonSerializer<TaskList>() {
override fun serialize(value: TaskList, gen: JsonGenerator, provider: SerializerProvider) {
gen.writeStartArray()
value.items.map { gen.writeObject(it) }
gen.writeEndArray()
}
}
private class TaskListDeSerializer : JsonDeserializer<TaskList>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): TaskList {
val taskArray = p.readValueAs(Array<Task>::class.java)
return TaskList(taskArray.toList())
}
}