Вот мое решение для этого.Решение в Kotlin.
Редактировать класс Blah
:
class Blah {
val type : String? = null
@ExcludeOnDeserialization // <- add this
val myObject : Foo? = null
}
Внутри статического класса:
inline fun <T : Annotation>findAnnotatedFields(
annotation: Class<T>,
clazz : Class<*>,
onFind : (Field) -> Unit
){
for(field in clazz.declaredFields){
if(field.getAnnotation(annotation)!=null){
field.isAccessible = true
onFind(field)
}
}
}
Создать новый класс и аннотацию:
@Target(AnnotationTarget.FIELD)
annotation class ExcludeOnDeserialization
class GsonExclusionStrategy : ExclusionStrategy {
override fun shouldSkipClass(clazz: Class<*>?): Boolean {
return clazz?.getAnnotation(ExcludeOnDeserialization::class.java) != null
}
override fun shouldSkipField(f: FieldAttributes?): Boolean {
return f?.getAnnotation(ExcludeOnDeserialization::class.java) != null
}
}
Прочитать корневой объект json:
...
val gson = GsonBuilder()
.addDeserializationExclusionStrategy(GsonExclusionStrategy())
.create()
val rootJsonObject = JsonParser().parse(rootJsonObjectAsString)
val blah = gson.fromJson(rootJsonObject, Blah::class.java)
findAnnotatedFields(
ExcludeOnDeserialization::class.java,
Blah::class.java
){ foundExcludedField -> // foundExcludedField = 'myObject' declared in 'Blah' class
val myObjectAsJsonObject
= rootJsonObject.asJsonObject.getAsJsonObject(foundExcludedField.name)
when (foundExcludedField.type) {
Foo::class.java -> {
when (blah.type) {
"A" -> {
foundExcludedField.set(
blah,
gson.fromJson(myObjectAsJsonObject, Bar::class.java)
)
}
"B" -> {
foundExcludedField.set(
blah,
gson.fromJson(myObjectAsJsonObject, Baz::class.java)
)
}
else -> return null
}
}
}
}
// The root json object has now fully been mapped into 'blah'
Вдохновение для этого решения пришло от этой статьи