java - 如果 Gson 序列化失败,如何跳过字段?
问题描述
例如,服务器响应#1 有name
对象:
{
"id":"vfa45f42",
"name": {
"firstName":"UserFirstName",
"lastName":"UserLastName"
}
}
但有时服务器响应#2 有name
其他用户对象的字符串(那是因为服务器有 MongoDB,在 v1 是String
,但在 v2 是Object
):
{
"id":"abfaf453",
"name":"OneSentenceUserName"
}
所以,如果我用 response#2 这个:
val type = object : TypeToken<User>() {}.type
gson.fromJson(responseString, type)
在哪里
data class User(val id:String, val name: Name)
data class Name(val firstName: String, val lastName: String)
错误是:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line ...
我希望name = null
它String
在 json
解决方案
保留您的实际类User
和Name
,您可以创建一个自定义TypeAdapter
并通过自己阅读创建一个完整Name
的单个name
字符串或完整的 JSON 对象。
class NameAdapter : TypeAdapter<Name>() {
@Throws(IOException::class)
override fun read(reader: JsonReader): Name? {
return when(reader.peek()) {
// if { "name": null }
JsonToken.NULL -> {
reader.nextNull()
null
}
// if { "name": "SomeString" }
JsonToken.STRING -> {
Name(reader.nextString(), "")
}
//if { "name": { "firstName": "some", "lastName": "thing" }
JsonToken.BEGIN_OBJECT -> {
var firstName = ""
var lastName = ""
reader.beginObject()
while (reader.hasNext()) {
val peek = reader.peek()
if(peek == JsonToken.END_OBJECT) break
else if(peek == JsonToken.NAME) {
when(reader.nextName()) {
// it will produce an exception if it isn't a string
"firstName" -> firstName = reader.nextString()
"lastName" -> lastName = reader.nextString()
}
}
}
reader.endObject()
Name(firstName, lastName)
}
else -> throw IOException("Unable to parse a name")
}
}
@Throws(IOException::class)
override fun write(writer: JsonWriter, value: Name?) {
if(value == null) {
writer.nullValue()
return
}
writer.beginObject()
writer.name("firstName")
writer.value(value.firstName)
writer.name("lastName")
writer.value(value.lastName)
writer.endObject()
}
}
然后您可以将此类型的适配器添加到您的 gson 构建器中。
val gson = GsonBuilder().registerTypeAdapter(Name::class.java, NameAdapter()).build()
它将在每种情况下正确反序列化名称并生成一个完整的Name
类。
推荐阅读
- zsh - 使用 zsh 以块的形式连接大量文件
- javascript - 有没有办法将像“1,2,3,4”这样的数字字符串转换为js中的数组?
- excel - 替换列表中的名称
- python-3.x - 从复数列表中删除非共轭
- c# - 将 CalendarDatePicker 中的整月存储在变量中
- javascript - Socket.io 和 Async 不返回值
- javascript - 无法读取 null 的属性“classList”| JS
- r - R6Class:初始化方法引发错误消息:“无法将绑定添加到锁定的环境”
- encoding - 是否有可变 Base64 安全编码?
- apache-pig - 在 Apache Pig 中每年获取 MAX 值