问题类似于 this
但不同之处在于 type
不包含在反序列化的 JSON 对象中,而是包含在外层(根)中。
像这样:
{
"type": "A",
"myObject" : { <- type is NOT stored in here
...
}
}
目的是将此 JSON 对象映射到 Blah
// Code is in Kotlin
interface Foo {
...
}
class Bar : Foo { // Map to this if 'type' is A
...
}
class Baz : Foo { // Map to this if 'type' is B
...
}
class Blah {
val type : String? = null
val myObject : Foo? = null
}
我如何制作 myObject
映射到 Bar
如果type
是A
和 Baz
如果type
是B
?
暂时,我求助于手动读取根 JSON 对象。任何帮助将非常感激。谢谢。
编辑:
尝试将根 JSON 对象映射到 Blah
时使用 Gson
fromJson
方法,我得到这个错误:Unable to invoke no-args constructor for class Foo
. - 但无论如何这是不正确的,因为我需要 myObject
专门映射到 Baz
或 Bar
.
最佳答案
这与您提到的问题非常相似。
您可以为 Blah
定义反序列化器并决定应该使用哪个类。
代码如下所示。
import com.google.gson.*
interface Foo {
fun bark()
}
class Bar : Foo { // Map to this if 'type' is A
override fun bark() {
print("bar")
}
}
class Baz : Foo { // Map to this if 'type' is B
override fun bark() {
print("baz")
}
}
class Blah(val type : String? = null, val myObject : Foo? = null) {
companion object {
const val TYPE_A = "A"
const val TYPE_B = "B"
}
}
class BlahJsonDeserializer: JsonDeserializer<Blah> {
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Blah {
val root = json?.asJsonObject
val type = root?.get("type")?.asString
var obj: Foo? = null
when(type ?: "") {
Blah.TYPE_A -> { obj = Bar() }
Blah.TYPE_B -> { obj = Baz() }
}
val blah = Blah(type, obj)
return blah
}
}
val json = "{'type': 'A', 'myObject': {}}"
val gsonBuilder = GsonBuilder()
gsonBuilder.registerTypeAdapter(Blah::class.java, BlahJsonDeserializer())
val gson = gsonBuilder.create()
val item = gson.fromJson<Blah>(json, Blah::class.java)
item.myObject?.bark() // bar
关于java - 使 Gson 为外部字段确定的接口(interface)类型工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54281035/