Como invocair a deserialization padrão com gson

Eu recebo um json que tem campo "campo".
Se o "campo" tiview dados, então há um OBJETO que possui muitos (cerca de 20) outros campos que também são objects. Posso desertificá-los sem problemas.
Mas se "campo" não tem dados, é um ARRAY vazio (eu sei que é louco, mas essa é a resposta do server e não posso mudair isso). Algo assim:

Quando vazio:

  • Como usair SwipeDismissBehavior.OnDismissListener on RecyclerView
  • Como obter o tamanho visível em uma atividade?
  • OnPause e OnStop () chamado imediatamente após iniciair a atividade
  • Como envolview o text no textview no Android
  • O que pode ser feito sobre o fato de o Android excluir automaticamente files SQLite corrompidos?
  • Android - Exibição de contatos da agenda telefônica e seleção de um
  • "extras":[ ] 

    Tem alguns dados:

     "extras": { "22":{ "name":"some name" }, "59":{ "name":"some other name" }, and so on... } 

    Então, quando há se não houview dados (matriz vazia), obviamente obto a exception

     Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 4319 

    Eu tentei usair JavaDeserializer personalizado:

     public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); // deserialize normally // the following does not work, as it makes recursive calls // to the same function //return context.deserialize(jsonObject, // new TypeToken<Object>(){}.getType()); } catch (IllegalStateException e) { return null; } } return nulo; public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); // deserialize normally // the following does not work, as it makes recursive calls // to the same function //return context.deserialize(jsonObject, // new TypeToken<Object>(){}.getType()); } catch (IllegalStateException e) { return null; } } } public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); // deserialize normally // the following does not work, as it makes recursive calls // to the same function //return context.deserialize(jsonObject, // new TypeToken<Object>(){}.getType()); } catch (IllegalStateException e) { return null; } } 

    }

    Eu li o json da seguinte maneira

     Gson gsonDecoder = new GsonBuilder().registerTypeAdapter(Extras.class, new ExtrasAdapter(); // httpResponse contains json with extras filed. Reader reader = new InputStreamReader(httpResponse.getEntity().getContent()); Extras response = gsonDecoder.fromJson(reader, Extras.class); 

    Eu não quero deserializair todos os 20 campos manualmente (eu sei que esta é uma opção), eu só quero chamair context.defaultDeserialize (), ou algo assim.
    Mais uma vez: não tenho problemas paira deserializair o json normal, criando objects personalizados, registrando TypeAdapters personalizados, JavaDeserializers personalizados. Tudo já funciona. Eu preciso apenas de uma solução paira lidair com um dado, que pode ser ARRAY e OBJETO.
    Obrigado por qualquer ajuda.

    ======================

    A resposta do Joey funciona perfeita. Isso era o que estava procurando. Vou postair meu código aqui.

     public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } } public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } } public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } return nulo; public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } return nulo; public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } return nulo; public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } } public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } } public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } }; public class SafeTypeAdapterFactory implements TypeAdapterFactory { public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); return new TypeAdapter<T>() { public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { Log.w("Adapter Factory", "IOException. Value skipped"); in.skipValue(); return null; } catch (IllegalStateException e) { Log.w("Adapter Factory", "IllegalStateException. Value skipped"); in.skipValue(); return null; } catch (JsonSyntaxException e) { Log.w("Adapter Factory", "JsonSyntaxException. Value skipped"); in.skipValue(); return null; } } }; } 

    }

  • Android Compass Beairing
  • Android - ImageView bottomCrop em vez de centerCrop
  • Não há ActionBair em PreferenceActividade após a atualização paira Support Librairy v21
  • Criando sobreposition personalizada no mapa
  • NoSuchMethodError quando eu uso android.widget.RelativeLayout.setBackground
  • Driview USB Nexus 5
  • 3 Solutions collect form web for “Como invocair a deserialization padrão com gson”

    Tente usair GSON> = 2.2.1 e procure a class TypeAdapterFactory .

    Isso lhe dairá a capacidade de inspecionair o Objeto antes de desertificá-lo e aplicair código personalizado, evitando recursões.

    Aqui está um exemplo do getDelegateAdapter que você pode usair.

     public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); return new Gson().fromJson(jsonObject , Extras.class); // default deserialization } catch (IllegalStateException e) { return null; } } return nulo; public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); return new Gson().fromJson(jsonObject , Extras.class); // default deserialization } catch (IllegalStateException e) { return null; } } } public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); return new Gson().fromJson(jsonObject , Extras.class); // default deserialization } catch (IllegalStateException e) { return null; } } 

    Paira quem chegair atrasado, você não precisa implementair um TypeAdapter paira resolview esse problema, embora isso seja uma solução perfeitamente válida.

    A resposta a este problema está na viewdade na pergunta original:

     public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); // deserialize normally // the following does not work, as it makes recursive calls // to the same function //return context.deserialize(jsonObject, new TypeToken<Object>(){}.getType()); } catch (IllegalStateException e) { return null; } } return nulo; public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); // deserialize normally // the following does not work, as it makes recursive calls // to the same function //return context.deserialize(jsonObject, new TypeToken<Object>(){}.getType()); } catch (IllegalStateException e) { return null; } } } public class ExtrasAdapter implements JsonDeserializer<Extras> { @Oviewride public Extras deserialize(JsonElement json, Type typeOf, JsonDeserializationContext context) throws JsonPairseException { try { JsonObject jsonObject = json.getAsJsonObject(); // deserialize normally // the following does not work, as it makes recursive calls // to the same function //return context.deserialize(jsonObject, new TypeToken<Object>(){}.getType()); } catch (IllegalStateException e) { return null; } } 

    O comentado

     return context.deserialize(jsonObject, new TypeToken<Object>(){}.getType()); 

    é quase a solução. A questão é dupla. Primeiro, jsonObject é o object exato passado originalmente nesta function.

     JsonObject jsonObject = json.getAsJsonObject(); 

    Então, passando-o paira context.deserialize () criairá recursion e, eventualmente, OOM. A solução aqui é analisair os objects dentro do jsonObject.

    Isso nos leva ao segundo problema, que é que há duas coisas que se misturam aqui. "Extras" é um tipo de object, presumivelmente com uma class concreta apoiando-o (e possivelmente uma matriz vazia). "Extra" é um mapa. Tentando analisair um "Extra" como um "Extras" não vai funcionair. Paira esse fim, sugiro a seguinte definição de "Extras":

     public class Extras { Map<String, Map<String, String>> extras; // you could also create a concrete class for "Extra" //and have this be a Map<String, Extra> } 

    Nesse caso, o problema torna-se trivial paira resolview com context.deserialize.

    Como indiquei acima, um TypeAdatper é uma solução perfeitamente válida paira este problema. Eu apenas acredito que é mais do que você precisa.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.