我必须将0
反序列化为false
,将1
反序列化为true
。
我创建了这个课程:
class IntBooleanDeserializer : JsonDeserializer<Boolean?> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Boolean? {
json?.let {
return json.asInt == 1
}
return null
}
}
并注册了它:
private val gson = GsonBuilder()
.registerTypeAdapter(Boolean::class.java, IntBooleanDeserializer())
.create()
为此创建了测试类:
data class BooleanClass(val value: Boolean?)
然后:
gson.fromJson("{\"value\": 0}", BooleanClass::class.java)
此代码抛出异常:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a boolean but was NUMBER at line 1 column 12 path $.value
似乎Gson没有将我的反序列化器用于Boolean?
,但成功地将其他自定义反序列化器用于其他类型(例如,用于枚举)。
为什么?
答案 0 :(得分:2)
您正在为Boolean::class.java
boolean
注册解串器,而您实际需要的类型Boolean?
正在转换为java.lang.Boolean
。
要获得java.lang.Boolean
,您必须使用Boolean::class.javaObjectType
进行注册。
您还可以找到所有原始 Java 类型的相同行为。
答案 1 :(得分:0)
受到@tynn 的回答和此post 的启发。我设计了两个 TypeAdater
来覆盖 Kotlin 中的 Boolean
和 Boolean?
类型。
private val TRUE_STRINGS: Array<String> = arrayOf("true", "1")
class BooleanObjectTypeAdapter : JsonDeserializer<Boolean?>, JsonSerializer<Boolean?> {
override fun serialize(src: Boolean?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
return if (src == null) {
JsonNull.INSTANCE
} else {
JsonPrimitive(src)
}
}
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Boolean? {
if (json == null || json.isJsonNull) {
return null
}
return when {
json !is JsonPrimitive -> false
json.isBoolean -> json.asBoolean
json.isNumber -> json.asNumber.toInt() == 1
json.isString -> TRUE_STRINGS.contains(json.asString.lowercase())
else -> false
}
}
}
class BooleanPrimitiveTypeAdapter : JsonDeserializer<Boolean>, JsonSerializer<Boolean> {
override fun serialize(src: Boolean?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
return if (src == null) {
JsonPrimitive(false)
} else {
JsonPrimitive(src)
}
}
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Boolean {
if (json == null || json.isJsonNull) {
return false
}
return when {
json !is JsonPrimitive -> false
json.isBoolean -> json.asBoolean
json.isNumber -> json.asNumber.toInt() == 1
json.isString -> TRUE_STRINGS.contains(json.asString.lowercase())
else -> false
}
}
}
您可以通过
注册这些适配器GsonBuilder()
.registerTypeAdapter(Boolean::class.javaObjectType, BooleanObjectTypeAdapter())
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanPrimitiveTypeAdapter())
.create()
我还创建了一个 gist 来保存这些并编写测试。