There is a good known case when we unwrap nested object and write its fields into the main object, and I need to make an inverse task.
I have a POJO:
class A {
private String id = "id1";
@JsonWrap("properties")
private String property1 = "...";
@JsonWrap("properties")
private String property2 = "...";
// getters and setters
}
Default serializer will produce as expected
{
"id": "id1",
"property1": "...",
"property2": "..."
}
But, my JSON should match some specification, and to do that, I need to wrap property1
and property2
inside properties
wrapper. So the result should looks like:
{
"id": "id1",
"properties":
{
"property1": "...",
"property2": "..."
}
}
I don't want to change the structure of the POJO so I see 3 possible ways:
Does anybody make such Serializer or maybe know another options to generate JSON with the structure I need?
For custom serializer
I want to reuse standard BeanSerializer, I dont want to write out all fields manually:
jgen.writeEndObject();
) You need change your model.
@JsonSerialize(using = ASerializer.class)
class A {
private String id;
private String property1;
private String property2;
// getters and setters
public static class ASerializer extends JsonSerializer<A> {
@Override
public void serialize(A value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("id", value.getId());
jgen.writeObjectFieldStart("properties");
jgen.writeStringField("property1", value.getProperty1());
jgen.writeStringField("property2", value.getProperty2());
jgen.writeEndObject();
jgen.writeEndObject();
}
}
}
Run in main:
A a = new A();
a.setId("id1");
a.setProperty1("...");
a.setProperty2("...");
ObjectMapper mapper = new ObjectMapper();
ObjectWriter writer = mapper.writer();
String json = writer.writeValueAsString(a);
System.out.println(json);
output:
{"id":"id1","properties":{"property1":"...","property2":"..."}}
It sounds like you need to create a Custom Serializer: http://wiki.fasterxml.com/JacksonHowToCustomSerializers
Of course, if you are creating Java objects from a similar JSON structure you'll likely need to create a Custom Deserializer as well.
Remember, you can always use reflection to create a 'generic' serializer if you find many of your objects share a similar structure.
To get that functionality without altering your model, take a look at writing a custom serializer to accomplish what Jackson can't figure out natively. We annotate the model class A
with specific directions to use a defined serializer, and then use the JsonGenerator
to specifically define the structure we are after.
@JsonSerialize(using = ASerializer.class)
class A {
private String field1;
private String innerField1;
private String innerField2;
// getters and setters
public static class ASerializer extends JsonSerializer<A> {
@Override
public void serialize(A value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeStartObject();
jgen.writeStringField("field1", value.getField1());
jgen.writeObjectFieldStart("wrapper");
jgen.writeStringField("innerField1", value.getInnerField1());
jgen.writeStringField("innerField2", value.getInnerField2());
jgen.writeEndObject();
jgen.writeEndObject();
}
}
}
I used a static inner class in this case, but feasibly you can place the Serializer wherever best fits your project structure based on visibility. For one-off special case serializers, this is what I tend to do.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.