Estoy usando una API muy extraña, su tipo de campo de datos es dinámico.
Si se produjo un error, el campo de datos será una cadena como esta:
{ "code": 2001, "data": "Error!" }Y si tiene éxito, el campo de datos será un objeto:
{ "code": 2000, "data": { "id": 1, "name": "example" } }Estoy usando el siguiente código de Kotlin para deserializarlo:
return Gson().fromJson(data, SimpleModel::class.java)La definición del modelo está abajo:
import com.google.gson.annotations.SerializedName class SimpleModel { @SerializedName("code") val code = 0 @SerializedName("data") val data: SimpleData = SimpleData() } class SimpleData { @SerializedName("id") val id = "" @SerializedName("name") val name = "" }Cuando no se produce ningún error, el código anterior funciona bien. Sin embargo, cuando ocurrió el error, se lanzó una excepción:
java.lang.IllegalStateException: Excepted BEGIN_OBJECT but was STRING at line 1 column x $path.data ¿Hay alguna manera de deserializar el campo de data a un objeto o cualquier cosa y determinar su tipo por código manualmente?
Deberá escribir un deserializador personalizado, que decida en qué tipo deserializar data , según el tipo de tiempo de ejecución del nodo, y registrar ese deserializador con su instancia de Gson . Desafortunadamente, no estoy familiarizado con la sintaxis de kotlin, por lo que solo puedo darle un pseudocódigo.
data de campo en SimpleModel deben ser Object o hacer que la clase sea genérica: SimpleModel<T> , y el campo también debe ser de tipo TJsonElement . JsonElement root = parseResponse(); root.getAsJsonObject().get("data").getAsString();getAs...() para verificar el tipo.SimpleModel .getAsJsonObject() , analice el objeto en SimpleData y configure este nuevo objeto en SimpleModel .Podrías usar mi respuesta aquí como inspiración. Aunque se trata de un mapeador de objetos, hace lo mismo: decide el tipo de objeto según el tipo de nodo y sigue aproximadamente el mismo algoritmo que describí anteriormente.
Además , esta guía tiene información sobre cómo escribir su propio deserialzer y registrarlo.