2012-08-23 16 views
11

Diciamo che ho le seguenti classi:GSON aggiungere automaticamente nomeclasse

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

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

Se corro questo attraverso una GSON sarà serializzare come segue:

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

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

Questo Fin qui tutto bene, ma io vorrebbero avere aggiunto il className per tutte le classi automaticamente con GSON, così ho ottenere il seguente risultato:

{ 
    "madDog" : { 
     "name":"Edvard", 
     "className":"Dog" 
    }, 
    "className" : "Animal" 
} 

Qualcuno sa se questo è possibile con qualche tipo di intercettatore o qualcosa con Gson?

risposta

3

Per questo sono necessari serializzatori personalizzati. Ecco un esempio per la classe degli animali di cui sopra:

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

allora avete bisogno di istanziare un nuovo GSON() dell'oggetto tramite GsonBuilder per il bene di attaccare i serializzatori, se lo desideri:

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

Questo non risolve il problema vero? Voglio utilizzare la serializzazione standard per tutti i campi, ma aggiungere un singolo campo aggiuntivo per il nome della classe: sembra un caso d'uso veramente normale. – mjaggard

+0

Il problema è che si desidera aggiungere un singolo campo alla normale serializzazione e la mia soluzione risolve il problema (specialmente senza fare affidamento su eventuali dipendenze extra). Capisco che è una specie di sofferenza, ma fuori dalla scatola non c'è/non sembra essere un modo per raggiungere questo semplice compito senza creare e registrare serializzatori personalizzati. –

14

Date un'occhiata a this: 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

Questo è esattamente ciò di cui ho bisogno! Quella lezione non è in Gson. Devo includere RuntimeTypeAdapterFactory.java nella mia base di codice? O c'è un modo per ottenerlo come una biblioteca? – paj28

+1

Sì, devi aggiungerlo al tuo codice. –

+0

Questo è anche pubblicato ora: https://mvnrepository.com/artifact/org.danilopianini/gson-extras/0.1.0 – pandaadb