2011-01-07 14 views
22

Tengo un problema al serializar un objeto usando Gson.¿Gson serializa POJO con el valor raíz incluido?

@XmlRootElement 
class Foo implements Serializable { 
    private int number; 
    private String str; 

    public Foo() { 
     number = 10; 
     str = "hello"; 
    } 
} 

Gson serializará esto en un JSON

{"number":10,"str":"hello"}.

Sin embargo, quiero que sea

{"Foo":{"number":10,"str":"hello"}},

así que básicamente incluye el elemento de nivel superior. Traté de googlear una manera de hacer esto en Gson, pero no tuve suerte. ¿Alguien sabe si hay una manera de lograr esto?

Gracias!

Respuesta

19

Necesita agregar el elemento en la parte superior del árbol de objetos. Algo como esto:

Gson gson = new Gson(); 
JsonElement je = gson.toJsonTree(new Foo()); 
JsonObject jo = new JsonObject(); 
jo.add("Foo", je); 
System.out.println(jo.toString()); 
// Prints {"Foo":{"number":10,"str":"hello"}} 
+2

bueno, esto significa que necesito para codificar el tipo de clase "Foo" en el elemento sin embargo. – fei

+0

@fei sí. Idealmente, lo que obtienes de Gson es correcto. La representación correcta del objeto 'Foo' en JSON es' {"number": 10, "str": "hello"} '. Si hay una clase que tiene Foo como su variable de instancia en ese caso, deberías haber esperado '{" foo ": {" number ": 10," str ":" hello "}}' - pero si quieres anteponer nombre de clase explícitamente, tendrá que agregarlo explícitamente. – Nishant

15

En lugar de codificar el tipo que puede hacer:

... 
jo.add(Foo.getClass().getSimpleName(), je); 
+2

Creo que esto debería ser un comentario de la otra respuesta y no una respuesta en sí misma. En realidad es un buen comentario, aunque – mbritto

-1

Si está utilizando Jackson API utilizan las siguientes líneas

mapper.configure (SerializationFeature.WRAP_ROOT_VALUE, cierto); mapper.configure (DeserializationFeature.UNWRAP_ROOT_VALUE, true);

+0

El título de la pregunta del estado es usar GSON y no jackson – dstarh

6

Una mejor forma de hacerlo es crear una clase contenedora y luego crear un objeto de Foo dentro de ella.

Código de ejemplo:

public class ResponseWrapper { 

    @SerializedName("Foo") 
    private Foo foo; 

    public Foo getFoo() { 
     return foo; 
    } 

    public void setFoo(Foo foo) { 
     this.foo= foo; 
    } 
} 

A continuación, puede analizar fácilmente a JSON usando:

new GsonBuilder().create().toJson(responseWrapperObj); 

que le dará la estructura deseada:

{"Foo":{"number":10,"str":"hello"}} 
+0

Esta es una respuesta mucho mejor. –

+0

No, realmente estás creando otro objeto ... en una aplicación pequeña con 3 modelos, está bien, pero mantén 40+ y escribe estos envoltorios ... –

Cuestiones relacionadas