Jackson Serialization: Field Wrapping

There is a well-known case when we expand a nested object and write its fields to the main object, and I need to do the inverse problem.

I have a POJO:

class A {
    private String id = "id1";

    @JsonWrap("properties")
    private String property1 = "...";

    @JsonWrap("properties")
    private String property2 = "...";

    // getters and setters
}

The default serializer will produce as expected.

{
    "id": "id1",
    "property1": "...",    
    "property2": "..."    
}

But my JSON must comply with certain specifications, and to do that I need to wrap property1and property2inside the propertieswrapper. The result should look like this:

{
    "id": "id1",
    "properties": 
    {
        "property1": "...",
        "property2": "..."
    }
}

I do not want to change the structure of the POJO, so I see 3 possible ways:

  • Create your own serializer. But, it seems to me, writing such a serializer will require more effort, and then serialize the objects with your hands.
  • Create a Java proxy object that will display the correct JSON structure and serialize such a proxy.
  • JSON . (, JSON).

- Serializer JSON , ?

custom serializer BeanSerializer, :

  • .
  • bean, , . ( jgen.writeEndObject();)
  • .
  • .
+3
3

.

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

:

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

:

{"id":"id1","properties":{"property1":"...","property2":"..."}}
0
0

, , , , . A , JsonGenerator , .

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

In this case, I used a static inner class, but perhaps you can place the Serializer wherever it best suits your project structure based on visibility. For disposable special event serializers, this is what I usually do.

0
source

Source: https://habr.com/ru/post/1693420/


All Articles