首页 > 解决方案 > Kotlin Gson 空值

问题描述

我正在尝试形成这种类型的 JSON:

"answer_id":123,
"question_id":4567,
"value":"null"

但是,我无法将 NULL 值放在值键上,似乎 Gson 只是忽略了该字段,所以在序列化之后我得到

"answer_id":123,
"question_id":4567

所以我的服务器抛出了错误的请求。我serializeNulls()在 Gson builder 中使用它应该允许可为空的值,但它对我不起作用。有谁知道是什么问题?

@Parcelize
data class AnswerHelperObject(@SerializedName("question_id") val questionId: Int,
                              @SerializedName("value") val value: String? = null,
                              @SerializedName("answer_id") val answerId: Int?)

    : Parcelable {}

标签: androidjsonkotlinnullgson

解决方案


由于您以字符串形式接收值,因此 Gson 会将其解析为字符串“null”,因此如果您希望将字段值设为 null,则可以编写自定义反序列化器。

AnswerHelperObject

data class AnswerHelperObject(
    var answer_id: Int,
    var question_id: Int,
    var value: String?
)

AnswerHelperObjectDeserializer

class AnswerHelperObjectDeserializer: JsonDeserializer<AnswerHelperObject>{
    override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): AnswerHelperObject {
        val answerHelperObject = Gson().fromJson(json.asJsonObject, AnswerHelperObject::class.java)
        if (answerHelperObject.value == "null") {
            answerHelperObject.value = null
        }
        return answerHelperObject
    }
}

您可以看到测试场景。

class AnswerHelperObjectTest {

    @Test
    fun answer_object_parse_as_null_string() {
        val json = "{\"answer_id\":123,\n" +
                "\"question_id\":4567,\n" +
                "\"value\":\"null\"}"

        val answerHelperObject = Gson().fromJson(json, AnswerHelperObject::class.java)
        // value is parsed as string of value null
        assertEquals(answerHelperObject.value, "null")
    }
    @Test
    fun answer_object_parse_null() {
        val json = "{\"answer_id\":123,\n" +
                "\"question_id\":4567,\n" +
                "\"value\":\"null\"}"

        val gson = GsonBuilder()
            .registerTypeAdapter(AnswerHelperObject::class.java, AnswerHelperObjectDeserializer())
            .create()

        val answerHelperObject = gson.fromJson(json, AnswerHelperObject::class.java)
        // value is deserialized as null
        assertEquals(answerHelperObject.value, null)
    }
}

推荐阅读