para libreria leer deserializar cadena java json gson

leer - libreria json para java



MĂșltiples GSON @ NombreSerializado por campo? (2)

En octubre de 2015, la versión 2.4 de Gson ( changelog ) agregó la capacidad de usar nombres alternativos / múltiples para @SerializedName al deserializar. ¡No se necesita más TypeAdapter personalizado!

Uso:

@SerializedName(value="name", alternate={"person", "user"})

https://google.github.io/gson/apidocs/com/google/gson/annotations/SerializedName.html

¿Hay alguna manera en Gson de asignar múltiples campos JSON a una única variable miembro de Java?

Digamos que tengo una clase de Java ...

public class MyClass { String id; String name; }

Quiero usar esta clase con dos servicios diferentes. Sin embargo, estos dos servicios difieren en cómo devuelven sus datos ...

{ "id": 2341, "person": "Bob" }

... y ...

{ "id": 5382, "user": "Mary" }

... respectivamente.

¿Hay alguna manera de asignar los campos "person" y "user" en la cadena JSON al campo de name en el objeto Java?

(Nota: solo necesito convertir una cadena JSON a un objeto Java, nunca al revés).


No se admite la definición de múltiples anotaciones @SerializedName en un campo en Gson.

Motivo: por defecto, la deserialización se gestiona con un LinkedHashMap y las claves se definen mediante los nombres de campo json entrantes (no los nombres de campo de la clase personalizada o los serializedNames) y existe una asignación de uno a uno. Puede ver la implementación (cómo funciona la deserialización) en el método read(JsonReader in) Adapter<T> de la clase interna ReflectiveTypeAdapterFactory .

Solución: Puede escribir un TypeAdapter personalizado que maneje user etiquetas json de name , person y user , y user mapee al campo de nombre de su clase personalizada MyClass :

class MyClassTypeAdapter extends TypeAdapter<MyClass> { @Override public MyClass read(final JsonReader in) throws IOException { final MyClass myClassInstance = new MyClass(); in.beginObject(); while (in.hasNext()) { String jsonTag = in.nextName(); if ("id".equals(jsonTag)) { myClassInstance.id = in.nextInt(); } else if ("name".equals(jsonTag) || "person".equals(jsonTag) || "user".equals(jsonTag)) { myClassInstance.name = in.nextString(); } } in.endObject(); return myClassInstance; } @Override public void write(final JsonWriter out, final MyClass myClassInstance) throws IOException { out.beginObject(); out.name("id").value(myClassInstance.id); out.name("name").value(myClassInstance.name); out.endObject(); } }

Caso de prueba:

String jsonVal0 = "{/"id/": 5382, /"user/": /"Mary/" }"; String jsonVal1 = "{/"id/": 2341, /"person/": /"Bob/"}"; final GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(MyClass.class, new MyClassTypeAdapter()); final Gson gson = gsonBuilder.create(); MyClass myClassInstance0 = gson.fromJson(jsonVal0, MyClass.class); MyClass myClassInstance1 = gson.fromJson(jsonVal1, MyClass.class); System.out.println("jsonVal0 :" + gson.toJson(myClassInstance0)); // output: jsonVal0 :{"id":5382,"name":"Mary"} System.out.println("jsonVal1 :" + gson.toJson(myClassInstance1)); // output: jsonVal1 :{"id":2341,"name":"Bob"}

Ejemplos sobre TypeAdapters.

Edición 2016.04.06: Como @Mathieu Castets ha escrito en su respuesta, ahora es compatible. (Esa es la respuesta correcta para esta pregunta).

cadena abstracta pública [] alternativa
Devuelve: los nombres alternativos del campo cuando se deserializa
Predeterminado: {}