2014-09-07 7 views
54

Gibt es in Gson eine Möglichkeit, mehrere JSON-Felder einer einzelnen Java-Objektelementvariablen zuzuordnen?Mehrere GSON @ SerializedName pro Feld?

Lassen Sie uns sagen, dass ich eine Java-Klasse haben ...

public class MyClass { 
    String id; 
    String name; 
} 

Ich möchte mit zwei verschiedenen Dienste diese einzelne Klasse verwenden. Allerdings unterscheiden sich diese beiden Dienste, wie sie ihre Daten zurück ...

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

... und ...

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

... sind.

Gibt es eine Möglichkeit, die Felder "person" und "user" in der JSON-Zeichenfolge dem Feld name im Java-Objekt zuzuordnen?

. (Anmerkung: ich nur jemals brauche von JSON-String zu Java-Objekt zu konvertieren - nie umgekehrt)

+0

Hier ist einfach und perfekte Erklärung https://futurestud.io/tutorials/gson-model-annotations-multiple-deserialization-names-with-serializedname –

Antwort

20

Es ist nicht Gson auf ein Feld zu definieren mehrere @SerializedName Anmerkungen unterstützt.

Grund: standardmäßig Deserialisierung ist mit einem LinkedHashMap und die Schlüssel verwaltet werden durch eingehende json Feldnamen (nicht die benutzerdefinierten Klasse Feldnamen oder die serializedNames) und es gibt eine Eins-zu-Eins-Abbildung definiert. Sie können die Implementierung (wie die Deserialisierung funktioniert) unter der ReflectiveTypeAdapterFactory Klasse Adapter<T> der Klasse read(JsonReader in) der Klasse sehen.

Lösung: Sie eine benutzerdefinierte schreiben TypeAdapter die name Griffe, person und user json-Tags und ordnet sie der benutzerdefinierten Klasse Namensfeld 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(); 
    } 
} 

Testfall:

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

Examples about TypeAdapters.

Bearbeiten 2016.04.06: Wie @ Mathieu Castets bei seiner Antwort geschrieben hat, wird es jetzt unterstützt. (Das ist die richtige Antwort auf diese Frage.)

public abstract String [] alternativer
Returns: die alternativen Namen von das Feld, wenn es deserialisiert wird
Standard: {}

+0

Hier ist einfach und perfekte Erklärung https://futurestud.io/tutorials/gson-model-annotations-multiple-deserialization-names-with-serializedname –

130

Im Oktober 2015 Gson Version 2.4 (changelog) hinzugefügt, um die Fähigkeit zum @SerializedName alternativen/mehr Namen zu verwenden, wenn Deserialisieren. Kein benutzerdefinierter TypeAdapter mehr nötig!

Verbrauch:

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

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

+0

Großartig. Vielen Dank. – Mulgard

+1

Speichert mich von einem anderen dummen Workaround und einigen wenn Bedingungen. Danke :) –

+0

Hier ist einfach und perfekte Erklärung https://futurestud.io/tutorials/gson-model-annotations-multiple-deserialization-names-with-serializedname –

Verwandte Themen