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"}
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: {}