【问题标题】:Kotlin Gson null valueKotlin Gson 空值
【发布时间】:2019-02-18 09:55:30
【问题描述】:

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

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

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

"answer_id":123,
"question_id":4567

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

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

    : Parcelable {}

【问题讨论】:

  • 它不应该是 -> "value":null ?
  • @jczerski 是的,它应该 :) 我的意思是,服务器需要这种响应。
  • 你确定是GSON的问题而不是http客户端的问题?
  • 好吧,如果你输入 null,我不会得到 JSON 中的字段值。似乎 Gson 的 serializeNulls() 选项不起作用。
  • 请添加您如何序列化的代码。你有代表那个 JSON 的 DTO 吗?

标签: android json kotlin null gson


【解决方案1】:

由于您接收字符串形式的值,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)
    }
}

【讨论】:

  • 在我看来,您不应该尝试这样做并将特定字符串反序列化为空。空值返回为"null" 字符串而不是null 值是API 错误,API 是应该修复此问题的地方。
  • 再次强调,这不是反序列化,而是序列化。我已经修复了这个错误,它是关于 Dagger2 提供的 GsonConverterFactory 的。我没有将 Gson 作为依赖项传递给工厂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 2019-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多