2014-04-07 15 views
9

Muszę serializować JSON z listy obiektów. Powstały JSON musi wyglądać następująco:Lista Jackson JSON z obiektem typu

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

jestem brakujący typ/klucz "model", kiedy po prostu serializacji to:

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

Zamiast tego po prostu tak:

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

Jak dodać "model" dla każdego obiektu bez konieczności pisania głupiej klasy opakowującej za pomocą właściwości "model"?

moich klas wyglądać następująco:

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

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

Twój JSON nie jest ważny; nazwy członków obiektów muszą być cytowane (wskazówka: "" jest prawidłową nazwą elementu JSON) – fge

+0

Czy możesz pokazać swoją klasę 'Model' i' Response'? – fge

+0

Naprawiono to, thx @fge – raoulsson

Odpowiedz

13

Nie ma wbudowanego sposób to zrobić. Musisz napisać własną JsonSerializer. Coś jak

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

} 

a następnie opisywanie pola models tak, że używa go

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

To serializacji jako

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

Jeśli obie postaci szeregowej i deserializacji to ty” Potrzebuję również niestandardowego deserializera.

2

Jest to podstarzały pytanie, ale nie jest zapewne bardziej idiomatycznych sposobem realizacji tego (używam jackson-databind:2.8.8):

Zdefiniuj ModelSerializer (który rozciąga StdSerializer zalecane przez Jackson), który drukuje swój model jak chcesz i używać @JsonSerialize(contentUsing = ...) nad swoim rodzaju kolekcji:

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

Tymczasem w innym pliku:

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

Teraz nie są zobowiązane do zaledwie List s modeli, ale może zastosować to do Collection s, Set s, rdzennych [] s, a nawet wartości Map s.

Powiązane problemy