由于Json元素为空字符串(“”)而非对象,Android App崩溃

时间:2019-03-04 23:14:05

标签: android json gson

我正在研究一个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”有时在没有分配任何值时会重新运行空字符串“”。我无权将返回类型更改为null。这正在使我的应用崩溃,因为我在这里期望有一个对象。 我收到以下错误: 预期为BEGIN_OBJECT,但为STRING

2 个答案:

答案 0 :(得分:1)

如果您无法修改服务器,请尝试在服务器响应中替换有问题的行,然后再将其传递给Gson解析器。像这样:

def reverse1(lst):
    rev_lst = []
    i = 0
    while(i < len(lst)):
       rev_lst.insert(0, lst[i])
       i += 1
    return rev_lst

def reverse2(lst):
    rev_lst = []
    i = len(lst) - 1
    while (i >= 0):
       rev_lst.append(lst[i])
       i -= 1
    return rev_lst

答案 1 :(得分:0)

您的应用程序(客户端)代码根据传递给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)
    }