usar tutorial libreria leer example deserializar como java json gson

tutorial - leer json en java



¿Por qué Gson de Json lanzar una JsonSyntaxException: Se esperaba algún tipo, pero era algún otro tipo? (2)

class Pojo { NestedPojo nestedPojo; }

en su json usted tiene un arsenal de nestedPojo así que usted cambia el código

NestedPojo[] nestedPojo;

o cambiar la cadena json

String json = "{/"nestedPojo/":{/"name/":null, /"value/":42}}";

(Esta publicación está destinada a ser una pregunta canónica con una respuesta de ejemplo proporcionada a continuación.)

Estoy tratando de deserializar algún contenido de JSON en un tipo POJO personalizado con Gson#fromJson(String, Class) .

Este pedazo de código

import com.google.gson.Gson; public class Sample { public static void main(String[] args) { String json = "{/"nestedPojo/":[{/"name/":null, /"value/":42}]}"; Gson gson = new Gson(); gson.fromJson(json, Pojo.class); } } class Pojo { NestedPojo nestedPojo; } class NestedPojo { String name; int value; }

lanza la siguiente excepción

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196) at com.google.gson.Gson.fromJson(Gson.java:810) at com.google.gson.Gson.fromJson(Gson.java:775) at com.google.gson.Gson.fromJson(Gson.java:724) at com.google.gson.Gson.fromJson(Gson.java:696) at com.example.Sample.main(Sample.java:23) Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189) ... 7 more

¿Por qué Gson no puede convertir correctamente mi texto JSON a mi tipo POJO?


A medida que el mensaje de excepción indica

Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo

mientras que la deserialización, Gson esperaba un objeto JSON, pero encontró una matriz JSON. Puesto que no podía convertir de uno a otro, lanzó esta excepción.

El formato JSON se describe aquí . En resumen, define los siguientes tipos: objetos, matrices, cadenas, números, null y los valores booleanos true y false .

En Gson (y la mayoría de los analizadores JSON), existen las siguientes asignaciones: una cadena JSON se correlaciona con una String Java; un número JSON se asigna a un tipo de Number Java; una matriz JSON se correlaciona con un tipo de Collection o un tipo de matriz; un objeto JSON se asigna a un tipo de Map Java o, por lo general, un tipo de POJO personalizado (no mencionado anteriormente); mapas null a null de Java y los valores booleanos asignan a true y false Java.

Gson itera a través del contenido JSON que proporciona y trata de deserializarlo al tipo correspondiente que ha solicitado. Si el contenido no coincide o no puede convertirse al tipo esperado, lanzará una excepción correspondiente.

En su caso, usted proporcionó el siguiente JSON

{ "nestedPojo": [ { "name": null, "value": 42 } ] }

En la raíz, se trata de un objeto JSON que contiene un miembro denominado nestedPojo que es una matriz JSON. Ese conjunto JSON contiene un solo elemento, otro objeto JSON con dos miembros. Teniendo en cuenta las asignaciones definidas anteriormente, se espera que este JSON para asignar a un objeto Java que tiene un campo llamado nestedPojo de algún tipo de Collection o matriz, donde ese tipo define dos campos denominados name y value , respectivamente.

Sin embargo, usted ha definido su tipo Pojo como tener un campo

NestedPojo nestedPojo;

que no es ni un tipo de matriz, ni un tipo de Collection . Gson no puede deserializar el JSON correspondiente para este campo.

En su lugar, tiene 3 opciones:

  • Cambie su JSON para que coincida con el tipo esperado

    { "nestedPojo": { "name": null, "value": 42 } }

  • Cambie su tipo Pojo para esperar una Collection o tipo de matriz

    List<NestedPojo> nestedPojo; // consider changing the name and using @SerializedName NestedPojo[] nestedPojo;

  • Escriba y registre un deserializador personalizado para NestedPojo con sus propias reglas de análisis. Por ejemplo

    class Custom implements JsonDeserializer<NestedPojo> { @Override public NestedPojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { NestedPojo nestedPojo = new NestedPojo(); JsonArray jsonArray = json.getAsJsonArray(); if (jsonArray.size() != 1) { throw new IllegalStateException("unexpected json"); } JsonObject jsonObject = jsonArray.get(0).getAsJsonObject(); // get only element JsonElement jsonElement = jsonObject.get("name"); if (!jsonElement.isJsonNull()) { nestedPojo.name = jsonElement.getAsString(); } nestedPojo.value = jsonObject.get("value").getAsInt(); return nestedPojo; } } Gson gson = new GsonBuilder().registerTypeAdapter(NestedPojo.class, new Custom()).create();