I have to serialize JSON from a list of Objects. The resulting JSON has to look like this:
{
"status": "success",
"models": [
{
"model": {
"id": 23,
"color": "red"
}
},
{
"model": {
"id": 24,
"color": "green"
}
}
]
}
I am missing the type/key "model" when I simply serialize this:
List<Model> list = new ArrayList<Model>(); // add some new Model(...)
Response r = new Response("success", list); // Response has field "models"
Instead I just get this:
{
"status": "success",
"models": [
{
"id": 23,
"color": "red"
},
{
"id": 24,
"color": "green"
}
]
}
How can I add "model" for each object without having to write a silly wrapper class with a property "model"?
My classes look like this:
public class Response {
private String status;
private List<Model> models;
// getters / setters
}
public class Model {
private Integer id;
private String color;
// getters / setters
}
There's no built-in way to do this. You'll have to write your own JsonSerializer
. Something like
class ModelSerializer extends JsonSerializer<List<Model>> {
@Override
public void serialize(List<Model> value, JsonGenerator jgen,
SerializerProvider provider) throws IOException {
jgen.writeStartArray();
for (Model model : value) {
jgen.writeStartObject();
jgen.writeObjectField("model", model);
jgen.writeEndObject();
}
jgen.writeEndArray();
}
}
and then annotate the models
field so that it uses it
@JsonSerialize(using = ModelSerializer.class)
private List<Model> models;
This would serialize as
{
"status": "success",
"models": [
{
"model": {
"id": 1,
"color": "red"
}
},
{
"model": {
"id": 2,
"color": "green"
}
}
]
}
If you're both serializing and deserializing this, you'll need a custom deserializer as well.
This is an oldish question, But there is an arguably more idiomatic way of implementing this (I'm using jackson-databind:2.8.8
):
Define a ModelSerializer
(That extends StdSerializer
as recommended by Jackson) that prints your model how you like and use the @JsonSerialize(contentUsing = ...)
over your collection type:
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", value);
jgen.writeEndObject();
}
}
Meanwhile, in another file:
class SomethingWithModels {
// ...
@JsonSerialize(contentUsing = ModelSerializer.class)
private Collection<Model> models;
// ...
}
Now you aren't bound to just List
s of models but may apply this to Collection
s, Set
s, Native []
s and even the values of Map
s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With