Search code examples
javajsonserializationjacksonjson-serialization

Serializing a pojo as a nested JSON dictionary


Given the simple POJO:

public class SimplePojo {
    private String key ;
    private String value ;
    private int thing1 ;
    private boolean thing2;

    public String getKey() {
           return key;
    }
    ...
}

I have no issue in serializing into something like so (using Jackson):

 {
    "key": "theKey",
    "value": "theValue",
    "thing1": 123,
    "thing2": true
  }

but what would really make me happy is if I could serialize that object as such:

 {
    "theKey" {
           "value": "theValue",
            "thing1": 123,
            "thing2": true
     }
  }

I'm thinking I would need a custom serializer, but where I'm challenged is in inserting a new dictionary, e.g.:

@Override
public void serialize(SimplePojo value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    gen.writeStartObject();
    gen.writeNumberField(value.getKey(), << Here be a new object with the remaining three properties >> );


}

Any suggestions?


Solution

  • You don't need a custom serializer. You can utilize @JsonAnyGetter annotation to produce a map that contains the desired output properties.
    The code below takes the above example pojo and produces the desired json representation.
    First, you have annotate all getter methods with @JsonIgnore in order for jackson to ignore them during serialization. the only method that will be called is the @JsonAnyGetter annotated one.

    public class SimplePojo {
        private String key ;
        private String value ;
        private int thing1 ;
        private boolean thing2;
    
        // tell jackson to ignore all getter methods (and public attributes as well)
        @JsonIgnore
        public String getKey() {
            return key;
        }
    
        // produce a map that contains the desired properties in desired hierarchy 
        @JsonAnyGetter
        public Map<String, ?> getForJson() {
            Map<String, Object> map = new HashMap<>();
            Map<String, Object> attrMap = new HashMap<>();
            attrMap.put("value", value);
            attrMap.put("thing1", thing1);  // will autobox into Integer
            attrMap.put("thing2", thing2);  // will autobox into Boolean
            map.put(key, attrMap);
            return map;
        }
    }