Десериализовать вложенное поле JSON с Джексоном в Котлине - PullRequest
0 голосов
/ 29 января 2019

Я уже десериализовал некоторое вложенное поле в 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 - это поле в бине.

Теперь мне нужно сделать нечто подобное в Котлине, но я не доволен тем, что у меня есть.Предполагая, что у меня есть класс 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 a var, а не val.

Есть ли хитрость Котлина, чтобы улучшить ситуацию в целом?

1 Ответ

0 голосов
/ 29 января 2019

Ради простоты я использовал 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), вы потеряете преимущества класса данных (toString() из коробки и т. Д.).

Вы будете присваивать этот параметр private var _createdAt при создании экземпляра класса.

Единственное, что будет экспонироваться извне, - это свойство без вспомогательного поля createAt (просто получатель в терминах Java).Таким образом, _createdAt нельзя изменить после создания экземпляра.

Теперь есть два случая:

  1. Если вы создадите экземпляр класса, для _createdAt будет установлено указанное вами значение.
  2. Если Джексон создает экземпляр класса, значение _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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...