2012-08-23 9 views
11

Lets sagen, dass ich die folgenden Klassen:Gson hinzufügen automatisch classname

public class Dog { 
    public String name = "Edvard"; 
} 

public class Animal { 
    public Dog madDog = new Dog(); 
} 

Wenn ich laufe dies ein Gson Trog wird es serialisiert, wie folgend:

GSon gson = new GSon(); 
String json = gson.toJson(new Animal()) 

result: 
{ 
    "madDog" : { 
     "name":"Edvard" 
    } 
} 

so weit so gut, aber ich würde gerne den className für alle Klassen automatisch mit Gson hinzugefügt haben, so bekomme ich das folgende Ergebnis:

Weiß jemand, ob dies mit einer Art Abfangjäger oder etwas mit Gson möglich ist?

Antwort

3

Sie benötigen dafür benutzerdefinierte Serialisierer. Hier ist ein Beispiel für die Klasse Animal oben:

public class AnimalSerializer implements JsonSerializer<Animal> { 
    public JsonElement serialize(Animal animal, Type typeOfSrc, JsonSerializationContext context) { 
     JsonObject jo = new JsonObject(); 

     jo.addProperty("className", animal.getClass().getName()); 
     // or simply just 
     jo.addProperty("className", "Animal"); 

     // Loop through the animal object's member variables and add them to the JO accordingly 

     return jo; 
    } 
} 

Dann müssen Sie zum Zwecke der Befestigung der Serializer ein neues Gson() Objekt über GsonBuilder instanziiert wie gewünscht:

Gson gson = new GsonBuilder() 
    .registerTypeAdapter(Dog.class, new DogSerializer()) 
    .registerTypeAdapter(Animal.class, new AnimalSerializer()) 
    .create(); 
+1

Dies gilt nicht wirklich das Problem lösen nicht wahr? Ich möchte Standard-Serialisierung für alle Felder verwenden, aber ein einzelnes zusätzliches Feld für den Klassennamen hinzufügen - es fühlt sich an wie ein wirklich normaler Anwendungsfall. – mjaggard

+0

Das Problem ist, dass Sie der normalen Serialisierung ein einzelnes Feld hinzufügen möchten, und meine Lösung löst dieses Problem (insbesondere ohne zusätzliche Abhängigkeiten). Ich verstehe, dass es eine Art von Schmerz ist, aber out of the box gab es keine Möglichkeit, diese einfache Aufgabe zu erreichen, ohne benutzerdefinierte Serialisierer zu erstellen und zu registrieren. –

14

Werfen Sie einen Blick auf dies: http://code.google.com/p/google-gson/source/browse/trunk/extras/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java

RuntimeTypeAdapterFactory<BillingInstrument> rta = RuntimeTypeAdapterFactory.of(
    BillingInstrument.class) 
    .registerSubtype(CreditCard.class); 
Gson gson = new GsonBuilder() 
    .registerTypeAdapterFactory(rta) 
    .create(); 

CreditCard original = new CreditCard("Jesse", 234); 
assertEquals("{\"type\":\"CreditCard\",\"cvv\":234,\"ownerName\":\"Jesse\"}", 
    gson.toJson(original, BillingInstrument.class)); 
+1

Das ist genau das, was ich brauche! Diese Klasse ist nicht in Gson. Muss ich RuntimeTypeAdapterFactory.java in meine Codebasis aufnehmen? Oder gibt es einen Weg, es als Bibliothek zu bekommen? – paj28

+1

Ja, Sie müssen es zu Ihrem Code hinzufügen. –

+0

Dies wird jetzt auch veröffentlicht: https://mvnrepository.com/artifact/org.danilopianini/gson-extras/0.1.0 – pandaadb

Verwandte Themen