2014-04-07 12 views
9

Ich muss JSON aus einer Liste von Objekten serialisieren. Das resultierende JSON hat wie folgt aussehen:Jackson JSON Liste mit Objekttyp

{ 
    "status": "success", 
    "models": [ 
     { 
      "model": { 
       "id": 23, 
       "color": "red" 
      } 
     }, 
     { 
      "model": { 
       "id": 24, 
       "color": "green" 
      } 
     } 
    ] 
} 

ich den Typ/Schlüssel „Modell“ bin fehlt, wenn ich dies einfach serialisiert:

List<Model> list = new ArrayList<Model>(); // add some new Model(...) 
Response r = new Response("success", list); // Response has field "models" 

Stattdessen ich dies nur erhalten:

{ 
    "status": "success", 
    "models": [ 
     { 
      "id": 23, 
      "color": "red" 
     }, 
     { 
      "id": 24, 
      "color": "green" 
     } 
    ] 
} 

Wie kann ich "Modell" für jedes Objekt hinzufügen, ohne eine dumme Wrapper-Klasse mit einer Eigenschaft "Modell" schreiben zu müssen?

Aussehen Meine Klassen wie folgt aus:

public class Response { 
    private String status; 
    private List<Model> models; 
    // getters/setters 
} 

public class Model { 
    private Integer id; 
    private String color; 
    // getters/setters 
} 
+0

Ihr JSON ist nicht gültig; Objektmembernamen müssen in Anführungszeichen gesetzt werden (Hinweis: "" ist ein gültiger JSON-Objektmembername) – fge

+0

Können Sie Ihre Klasse 'Model' und die Klasse 'Response' anzeigen? – fge

+0

Das wurde behoben, thx @fge – raoulsson

Antwort

13

Es gibt keinen integrierten Weg, dies zu tun. Sie müssen Ihre eigene JsonSerializer schreiben. So etwas wie

class ModelSerializer extends JsonSerializer<List<Model>> { 

    @Override 
    public void serialize(List<Model> value, JsonGenerator jgen, 
      SerializerProvider provider) throws IOException, 
      JsonProcessingException { 
     jgen.writeStartArray(); 
     for (Model model : value) { 
      jgen.writeStartObject(); 
      jgen.writeObjectField("model", model); 
      jgen.writeEndObject();  
     } 
     jgen.writeEndArray(); 
    } 

} 

und dann mit Anmerkungen versehen, die models Feld, so dass sie es verwendet

@JsonSerialize(using = ModelSerializer.class) 
private List<Model> models; 

Dies als

{ 
    "status": "success", 
    "models": [ 
     { 
      "model": { 
       "id": 1, 
       "color": "red" 
      } 
     }, 
     { 
      "model": { 
       "id": 2, 
       "color": "green" 
      } 
     } 
    ] 
} 

serialisiert werden würde, wenn Sie beide Serialisierung und Deserialisierung dies sind, Sie‘ Ich brauche auch einen benutzerdefinierten Deserializer.

2

Dies ist eine ältliche Frage, aber es ist ein wohl mehr idiomatische Weg, dies umzusetzen (Ich verwende jackson-databind:2.8.8):

definieren ModelSerializer (Das reicht StdSerializer wie von Jackson empfohlen), das druckt Ihr Modell wie Sie mögen und verwenden Sie die @JsonSerialize(contentUsing = ...) über Ihre Sammlung Typ:

class ModelSerializer extends StdSerializer<Model> { 

    public ModelSerializer(){this(null);} 
    public ModelSerializer(Class<Model> t){super(t);} // sets `handledType` to the provided class 

    @Override 
    public void serialize(List<Model> value, JsonGenerator jgen, 
      SerializerProvider provider) throws IOException, 
      JsonProcessingException { 
     jgen.writeStartObject(); 
     jgen.writeObjectField("model", model); 
     jgen.writeEndObject(); 
    } 
} 

Zwischenzeit in einer anderen Datei:

class SomethingWithModels { 
    // ... 
    @JsonSerialize(contentUsing = ModelSerializer.class) 
    private Collection<Model> models; 
    // ... 
} 

Jetzt nur List s Modelle gebunden sind Sie nicht, aber kann dies zu Collection s gelten, Set s Native [] s und sogar die Werte von Map s.

Verwandte Themen