Приложение Android падает, так как элемент Json является пустой строкой (""), а не объектом - PullRequest
0 голосов
/ 05 марта 2019

Я работаю над проектом Android и использую RxAndroid, Retrofit для вызова API и получения json.JSON выглядит примерно так:

{
    "result": [
        {
            "parent": "jhasj",
            "u_deviation": "skasks",
            "caused_by": "ksks",
            "u_owner_mi": {
                "link": "https://gddhdd.service-now.com/api/now/v1/table/sys_user/ghtytu",
                "value": "ghtytu"
            },
            "impact": "",  
}
]
}

Я использую gson для анализа Json.Проблема в том, что "u_owner_mi" иногда перезапускает пустую строку "", когда ей не присвоено значение.У меня нет доступа, чтобы изменить тип возвращаемого значения на ноль.Это приводит к сбою приложения, так как я ожидаю, что здесь будет объект.Я получаю следующую ошибку: Ожидается BEGIN_OBJECT, но имеет значение STRING

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

Если вы не можете изменить сервер, попробуйте заменить ошибочную строку в ответе сервера, прежде чем передавать его анализатору Gson.Что-то вроде:

String safeResponse = serverResponse.replace("\"u_owner_mi\": \"\"", "\"u_owner_mi\": null");
0 голосов
/ 05 марта 2019

Код вашего приложения (клиента) ожидает объект в соответствии с контрактом, указанным в классе, который вы передаете GSON.Ваше приложение ведет себя как следует и громко вылетает.Вам следует подумать о том, чтобы ваш сервер возвращал "u_owner_mi" : null вместо пустой строки, предполагая, что у вас есть контроль над этим.Поле u_owner_mi на стороне клиента должно иметь тип , допускающий значение nullable .

Если у вас нет возможности исправить API, вы также можете написать собственный десериализатор.

Предположим, что ваш класс результата и подобъект:

data class Result(
    val parent: String,
    val owner: Any?
)

data class Owner(
    val link: String,
    val value: String
)

Десериализатор может быть:

class ResultDeserializer : JsonDeserializer<Result> {
    override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): Result {
        val jsonObject = json.asJsonObject
        val ownerProperty = jsonObject.get("owner")
        return Result(
            parent = jsonObject.get("parent").asString,
            owner = if (ownerProperty.isJsonObject) context?.deserialize<Owner>(ownerProperty.asJsonObject, Owner::class.java)
                    else ownerProperty.asString
        )
    }
}

Наконец, чтобы добавить десериализатор:

    @Test
    fun deserialization() {
        val gson = GsonBuilder().registerTypeAdapter(Result::class.java, ResultDeserializer()).create()
        val result1 = gson.fromJson<Result>(jsonWithObject, Result::class.java)
        val result2 = gson.fromJson<Result>(jsonWithEmpty, Result::class.java)
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...