2012-08-23 14 views
11

Digamos que tengo las siguientes clases:Gson añadir automáticamente nombre de clase

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

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

Si funciono esto a lo largo de un Gson Será serializarlo de la siguiente manera:

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

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

este momento tan bueno, pero Me gustaría haber agregado el nombre de clase para todas las clases automáticamente con Gson, así que obtengo el siguiente resultado:

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

¿Alguien sabe si esto es posible con algún tipo de interceptores o algo con Gson?

Respuesta

3

Necesitará serializadores personalizados para esto. He aquí un ejemplo de la clase de animal arriba:

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

Luego hay que crear una instancia de un nuevo Gson() objeto a través GsonBuilder por el bien de la fijación de los serializadores según se desee:

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

Esto realmente no resuelve el problema, ¿o sí? Quiero utilizar la serialización estándar para todos los campos, pero agrego un único campo adicional para el nombre de la clase: se siente como un caso de uso realmente normal. – mjaggard

+0

El problema es que desea agregar un solo campo a la serialización normal, y mi solución resuelve ese problema (especialmente sin depender de dependencias adicionales). Entiendo que es un poco doloroso, pero de entrada no había/no parece ser una forma de lograr esta simple tarea sin crear y registrar serializadores personalizados. –

14

Tome un vistazo a esto: 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

¡Esto es exactamente lo que necesito! Esa clase no está en Gson. ¿Debo incluir RuntimeTypeAdapterFactory.java en mi código base? ¿O hay alguna forma de obtenerlo como una biblioteca? – paj28

+1

Sí, necesita agregarlo a su código. –

+0

Esto también se publica ahora: https://mvnrepository.com/artifact/org.danilopianini/gson-extras/0.1.0 – pandaadb

Cuestiones relacionadas