我过去已经按照https://www.baeldung.com/jackson-nested-values(第5节)中的说明反序列化了Java中的某些嵌套字段:
@JsonProperty("brand")
private void unpackNested(Map<String,Object> brand) {
this.brandName = (String)brand.get("name");
Map<String,String> owner = (Map<String,String>)brand.get("owner");
this.ownerName = owner.get("name");
}
ownerName
是bean中的一个字段。
现在,我需要在Kotlin中做类似的事情,但是我对到目前为止的情况不满意。假设我有一个具有MyPojo
字段的createdAt
类,但是在表示它的JSON中,该字段嵌套在metadata
属性下:
data class MyPojo(var createdAt: LocalDateTime = LocalDateTime.MIN) {
@JsonProperty("metadata")
private fun unpackNested(metadata: Map<String, Any>) {
var createdAtAsString = metadata["createdAt"] as String
this.createdAt = LocalDateTime.parse(createdAtAsString,DateTimeFormatter.ISO_DATE_TIME)
}
}
我在这里不喜欢的一件事是我被迫将createdAt
设为var
,而不是val
。
这里是否有Kotlin技巧可以使整体状况更好?
答案 0 :(得分:0)
为简单起见,我将Int
用作createdAt
的类型。
您可以这样做:
class JsonData(createdAt: Int = 0) {
private var _createdAt: Int = createdAt
val createdAt: Int
get() = _createdAt
@JsonProperty("metadata")
private fun unpackNested(metadata: Map<String, Any>) {
_createdAt = metadata["createdAt"] as Int
}
}
createdAt
将是具有默认值的参数。由于数据类的构造函数只能具有属性(var
/ val
),因此您将失去data class(现成的toString()
等优点)。>
在实例化该类时,您将将此参数分配给private var _createdAt
。
唯一暴露给外部的是没有后备字段createAt
的属性(用Java术语来说就是吸气剂)。因此,_createdAt
实例化后无法更改。
现在有两种情况:
_createdAt
将被设置为您指定的值。 _createdAt
的调用将覆盖unpackNested
的值。这里是一个例子:
val jsonStr = """{
"metadata": {
"createdAt": 1
}
}
""".trimIndent()
fun main() {
val objectMapper = ObjectMapper()
// Jackson does instantiation
val jsonData = objectMapper.readValue(jsonStr, JsonData::class.java)
// you do it directly
JsonData(5)
}