Gson tiene un manejo especial para deserializar algunas matrices de un solo componente en un tipo que no sea de matriz. Por ejemplo, int data = gson.fromJson("[3]", int.class);
asignaría el valor int 3 a los datos.
Por supuesto, no se requiere deserializar una matriz de componente único en un tipo que no sea de matriz. Por ejemplo, el ejemplo anterior podría deserializarse como int[] data = gson.fromJson("[3]", int[].class);
.
Gson también a menudo deserializará un valor que no sea de Cadena en una Cadena, cuando se le solicite. Aplicando esto al primer ejemplo, String data = gson.fromJson("[3]", String.class);
funciona igual de bien.
Tenga en cuenta que no funciona decirle a Gson que deserialice el primer ejemplo como tipo Object. Object data = gson.fromJson("[3]", Object.class);
da como resultado una excepción de análisis quejándose de que [3] no es primitivo.
Aplicado al ejemplo en la pregunta original anterior, si es aceptable tratar todos los valores como cadenas, entonces la deserialización se vuelve simple.
// output:
// hello 1 2
// world 3 2
public class Foo
{
static String jsonInput =
"[" +
"[\"hello\",1,[2]]," +
"[\"world\",3,[2]]" +
"]";
public static void main(String[] args)
{
Gson gson = new Gson();
String[][] data = gson.fromJson(jsonInput, String[][].class);
for (String[] data2 : data)
{
for (String data3 : data2)
{
System.out.print(data3);
System.out.print(" ");
}
System.out.println();
}
}
}
Por desgracia, con Gson no he sido capaz de averiguar un enfoque deserialización simple que permitiría la "mejor" la unión a tipos más específicos y mixtos en una matriz, ya que Java no proporciona una sintaxis para definir una matriz de tipo mixto. Por ejemplo, el tipo preferido de la colección en la pregunta original podría ser List<List<String, int, List<int>>>
, pero no es posible definirlo en Java. Por lo tanto, debe contentarse con List<List<String>> (or String[][])
, o recurrir a un enfoque con más análisis "manual".
(Sí, Java permite una declaración de tipo de List<List<Object>>
, pero Object
no es un tipo lo suficientemente específico para deserializar significativa a. También, como se ha discutido, tratando de deserializar [3] para objetos como resultado una excepción de análisis sintáctico.)
Pequeña actualización: Recientemente tuve que deserializar algunos JSON descuidados que incluían una estructura no muy diferente de la de la pregunta original. Terminé usando un deserializador personalizado para crear un objeto a partir de la desordenada matriz JSON. Similar al siguiente ejemplo.
// output:
// [{MyThreeThings: first=hello, second=1, third=[2]},
// {MyThreeThings: first=world, second=3, third=[4, 5]}]
import java.lang.reflect.Type;
import java.util.Arrays;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
public class FooToo
{
static String jsonInput =
"[" +
"[\"hello\",1,[2]]," +
"[\"world\",3,[4,5]]" +
"]";
public static void main(String[] args)
{
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(MyThreeThings.class, new MyThreeThingsDeserializer());
Gson gson = gsonBuilder.create();
MyThreeThings[] things = gson.fromJson(jsonInput, MyThreeThings[].class);
System.out.println(Arrays.toString(things));
}
}
class MyThreeThings
{
String first;
int second;
int[] third;
MyThreeThings(String first, int second, int[] third)
{
this.first = first;
this.second = second;
this.third = third;
}
@Override
public String toString()
{
return String.format(
"{MyThreeThings: first=%s, second=%d, third=%s}",
first, second, Arrays.toString(third));
}
}
class MyThreeThingsDeserializer implements JsonDeserializer<MyThreeThings>
{
@Override
public MyThreeThings deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
JsonArray jsonArray = json.getAsJsonArray();
String first = jsonArray.get(0).getAsString();
int second = jsonArray.get(1).getAsInt();
JsonArray jsonArray2 = jsonArray.get(2).getAsJsonArray();
int length = jsonArray2.size();
int[] third = new int[length];
for (int i = 0; i < length; i++)
{
int n = jsonArray2.get(i).getAsInt();
third[i] = n;
}
return new MyThreeThings(first, second, third);
}
}
La guía del usuario Gson hace deserialización de colecciones de tipos mixtos manejo de la cubierta con un ejemplo similar como esto en the "Serializing and Deserializing Collection with Objects of Arbitrary Types" section.
su JSON es _wrong_. – Nishant
El código es exactamente como lo recibo del servidor ... lamentablemente no puedo cambiar los datos que recibo. Por supuesto, eso no hace que los datos JSON sean correctos. : P – Fofx
Posible duplicado de [matriz JSON deserializar Gson con múltiples tipos de objetos] (https://stackoverflow.com/questions/36780871/gson-deserialize-json-array-with-multiple-object-types) – ed22