在Kotlin中使用Jackson反序列化嵌套的json字段

zzzyeukh  于 2023-05-23  发布在  Kotlin
关注(0)|答案(2)|浏览(154)

我已经在Java中反序列化了一些嵌套字段,遵循https://www.baeldung.com/jackson-nested-values的说明(第5节):

@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技巧可以让这里的事情变得更好?

lb3vh1jj

lb3vh1jj1#

为了简单起见,我使用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术语中只是一个getter)。因此,_createdAt在示例化后不能更改。
现在有两种情况:
1.如果示例化该类,_createdAt将被设置为您指定的值。
1.如果Jackson示例化了类,_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)
}
c7rzv4ha

c7rzv4ha2#

请检查这是否适合你

class JsonData() {
 var createdAt by Delegates.notNull<Int>()

 @JsonProperty("metadata")
 private fun unpackNested(metadata: Map<String, Any>) {
     createdAt =  metadata["createdAt"] as Int
 }
}

相关问题