Deserialización de tipos genéricos con GSON

Tengo algunos problemas con la implementación de Json Deserialization en mi aplicación de Android (con la biblioteca de Gson)

He hecho clase como esta

public class MyJson<T>{ public List<T> posts; } 

Y la llamada de Deserialización es:

 public class JsonDownloader<T> extends AsyncTask<Void, Void, MyJson<T>> { ... protected MyJson<T> doInBackground(Void... params) { ... Reader reader = new InputStreamReader(content); GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson<T>>() {}.getType(); result = gson.create().fromJson(reader, collectionType); ... } } 

El problema es que result.posts lista después de la llamada sostiene una matriz de objetos LinkedTreeMap (con valores correctos por lo que el problema es deserialización) en lugar de MyJson objetos. Cuando utilizo MyObject en lugar de T todo está funcionando bien y MyObject es correcto.

Entonces, ¿hay alguna manera de implementar la llamada de deserialización sin crear deserializador personalizado?

¿Has probado?

 gson.create().fromJson(reader, MyJson.class); 

EDITAR

Después de leer esta publicación, parece que el uso de Type es correcto. Creo que su problema es el uso de T Usted debe recordar que con Java hay tipo de borrado. Esto significa que en tiempo de ejecución todas las instancias de T son reemplazadas por Object . Por lo tanto, en tiempo de ejecución lo que está pasando GSON es realmente MyJson<Object> . Si lo intentaste con una clase concreta en lugar de <T> creo que funcionaría.

Google Gson – deserializar lista <class> objeto? (Tipo genérico)

Debe especificar el tipo de T en el momento de la deserialización. ¿Cómo se crearía tu List de posts si Gson no sabía qué Type de instancia? No puede quedarse para siempre. Por lo tanto, se proporciona el tipo T como un parámetro de Class .

Ahora suponiendo que el tipo de posts era String usted deserializaría MyJson<String> como (también he añadido un parámetro String json para la sencillez; leería de su reader como antes):

 doInBackground(String.class, "{posts: [\"article 1\", \"article 2\"]}"); protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) { GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson<T>>(){}.getType(); MyJson<T> myJson = gson.create().fromJson(json, collectionType); System.out.println(myJson.getPosts()); // ["article 1", "article 2"] return myJson; } 

Similarmente, para deserializar un MyJson de objetos Boolean

 doInBackground(Boolean.class, "{posts: [true, false]}"); protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) { GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson<T>>(){}.getType(); MyJson<T> myJson = gson.create().fromJson(json, collectionType); System.out.println(myJson.getPosts()); // [true, false] return myJson; } 

He asumido MyJson<T> para que mis ejemplos sean como

 public class MyJson<T> { public List<T> posts; public List<T> getPosts() { return posts; } } 

Por lo tanto, si estaba buscando deserializar una List<MyObject> , invocaría el método como

 // assuming no Void parameters were required MyJson<MyObject> myJson = doInBackground(MyObject.class); 

Así que la respuesta anterior no funcionó para mí, después de prueba y error que es cómo mi código terminó:

 public class AbstractListResponse<T> { private List<T> result; public List<T> getResult() { return this.result; } } 

La parte importante aquí es la firma del método, incluyendo el '<T>' a la izquierda.

 protected <T> AbstractListResponse<T> parseAbstractResponse(String json, TypeToken type) { return new GsonBuilder() .create() .fromJson(json, type.getType()); } 

Al llamar a Gson, el método recibe el TypeToken del objeto genérico.

 TypeToken<AbstractListResponse<MyDTO>> typeToken = new TypeToken<AbstractListResponse<MyDTO>>() {}; AbstractListResponse<MyDTO> responseBase = parseAbstractResponse(json, typeToken); 

Y finalmente el TypeToken puede usar MyDTO, o incluso un objeto simple, apenas MyDTO.

  • El envío de JSON como datos adicionales en una transmisión de Android a través de ADB se formatea incorrectamente
  • org.json.JSONObject no se puede convertir en JSONArray
  • Json Parsing de Url en Android, no funciona
  • Problema al analizar JSON
  • Lectura de JSON con Retrofit
  • "Text1 / Text2" La cadena se reemplaza por "Text1 \ / Text2" en android
  • Análisis de la cadena JSON de la URL (RESTful webservice) mediante las bibliotecas GSON. Androide
  • Convertir objeto complejo de Java en Json
  • Error org.json.JSONException: No hay valor para PROJECT_NAME Este es mi json
  • Google Analytic "GET A CONFIGURATION FILE" no me permite seleccionar mi cuenta
  • Cordova / Phonegap / Ionic App - tienda local de imágenes remotas
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.