Consumo una API que me da este tipo de JSON:
{ "data": { "name": "Start", "pid": "1", "position": { "data": { "x": "31", "y": "330" }, "metadata": "empty" } }, "metadata": "empty" }
He creado las clases con objetos con la misma estructura que el JSON anterior. Uso la retrofit
de actualización en Android, que en su interior usa GSON
para analizar el JSON.
Mis clases modelo serían así:
MResponse.class
public class MResponse { @SerializedName("data") public User user; String metadata; }
Usuario.clase
public class User { public String name; public String pid; @SerializedName("position") public PositionData positionData; }
PositionData.clase
public class PositionData { @SerializedName("data") public Position position; public String metadata; }
Posición.clase
public class Position { public String x; public String y; }
Ahora esto funciona bien para mí. Pero como puede ver, para cada modelo, tengo que crear un padre que tendrá la misma estructura, solo cambia al hijo. Este hecho duplica las clases que uso para mis modelos. Me gustaría preguntar si hay una mejor manera de evitar todas estas clases.
No quiero usar clases internas. Estaba pensando que los muchachos que han hecho el JSON de esta manera deben haber tenido una razón por la que lo hicieron así y también una forma de facilitar el análisis.
Por lo general, estaba acostumbrado a analizar este tipo de estructura JSON:
{ "data": { "name": "Start", "pid": "1", "position": { "x": "31", "y": "330" } } }
Y aquí es más fácil si siguiera la solución anterior.
EDITAR
También cualquier solución en Kotlin es bienvenida.
EDITAR 2
Solución para Kotlin aquí
No creo que tu pedido sea posible. Si hay una solución, simplemente crearía clases intermedias que harían más o menos lo mismo que usted está haciendo.
En Kotlin, haría lo anterior así. Siéntase libre de ponerlo incluso en un archivo .kt
:
data class MResponse(@SerializedName("data") val user: User, val metadata: String) data class User(val name: String, val pid: String, @SerializedName("position") val positionData: PositionData) data class PositionData(@SerializedName("position") val position: Position, val metadata: String) data class Position(val x: String, val y: String)
Bueno, la solución que estaba pidiendo era bastante simple en mi opinión, simplemente no la sabía al principio.
Basado en el código fuente de Retrofit
y algunas otras respuestas relacionadas con los Java generics
, esta fue la respuesta a mi problema:
public class DataResponse<T, R> { public T data; @SerializedName("meta") public R metadata; }
y este es un ejemplo de cómo puedo usarlo:
Observable<DataResponse<User, BaseMeta>> getUser()
Para mí esta fue la solución. Si hay mejores soluciones por ahí, estoy listo para aceptarlas.