Как я могу конвертировать пустые объекты как ноль с моши и дооснащения? - PullRequest
0 голосов
/ 14 мая 2019

Я использую retrofit2 + Moshi в Kotlin для подключения к серверу.

Все ответы обернуты атрибутом result .Я создал общий класс данных , как показано ниже

@JsonClass(generateAdapter = true)
data class CommonResponse<T>(val result: T?)

Это работает безупречно, если атрибут результата не пуст, например:

{
    "result": {
        "bar": 1
    }
}

Наличие класса данныхFoo и использование универсального с Foo

data class Foo(val bar: Int)

interface {

    @Path("/foo")
    fun getFoo(): CommonResponse<Foo>
}

Но если атрибут result пуст, как показано ниже

{
  "result": {}
}

Я получаю JsonDataException из-за bar не может быть нулевым.

Есть ли способ для случаев, когда атрибут результата является пустым, считать его пустым с использованием универсального адаптера ?

На данный момент я перехватил JsonDataExceptionисключения и возвращают ноль для этих случаев, но я не доволен этим решением из-за того, что результаты без данных являются действительными ответами.Кроме того, я не смогу отличить ответ без результата или от неправильного ответа.

Есть идеи?

ПРИМЕЧАНИЕ. Я не могу изменить ответы сервера.

Ответы [ 2 ]

0 голосов
/ 23 мая 2019

Чтобы установить нулевое значение результата, если JSON пуст, вам нужно будет создать собственный настраиваемый адаптер для CommonResponse.Поэтому прежде всего вам не нужно генерировать адаптер для CommonResponse:

data class CommonResponse<T>(val result: T?)
data class Foo(val bar: Int)

... Затем вам нужно создать собственный адаптер для CommonResponse типа Foo:

class CommonResponseAdapterFoo {

    @FromJson
    fun fromJson(reader: JsonReader): CommonResponse<Foo>{
        var fooObj: Foo? = null

        while (reader.hasNext()) {
            reader.beginObject()
            if (reader.nextName() == "result") {
                reader.beginObject()
                if (reader.hasNext()) {
                    if (reader.nextName() == "bar") {
                        val barValue = reader.nextInt()
                        fooObj = Foo(barValue)
                    }
                }
                reader.endObject()

            }
            reader.endObject()
        }

        return CommonResponse(fooObj)
    }
}

... а затем вам нужно добавить этот пользовательский адаптер в ваш экземпляр moshi:

val moshi = Moshi.Builder().add(CommonResponseAdapterFoo()).build()

Если вы упаковываете несколько типов в CommonResponse, то вам, возможно, придется создать несколько пользовательских адаптеров для размещения всех различных типов

0 голосов
/ 22 мая 2019

Есть ли способ для случаев, когда атрибут результата является пустым, считать его нулевым?

Да, необходимо сделать панель свойств обнуляемой, поскольку это исключение для Int?, и добавить значение по умолчанию для свойства, чтобы, если оно отсутствует, для него можно было установить значение NULL. Так что измените data class Foo(val bar: Int) на data class Foo(val bar: Int? = null)

Это установит нулевое значение bar для следующего JSON:

{
    "result": {
        "bar": null
    }
}

... и

{
    "result": {}
}
...