Search code examples
javajsonjacksonunmarshallingobject-object-mapping

Convert a part of Json to HashMap using Jackson ObjectMapper


I am trying to unmarshall a json file in a way such that few properties of Json are mapped into a HashMap that is present in my model class.Rest of the properties are mapped to the respective fields of the class.Please find the Json below:

{
         "_id":2,
         "Name":"xyz",
         "Age":20,
         "MEMO_TEXT":"yyy",
         "MEMO_LINK":"zzz",
         "MEMO_DOB":"",
         "MEMO_USERNAME":"linie orange",
         "MEMO_CATEGORY":2,
         "MEMO_UID":"B82071415B07495F9DD02C152E4805EC"
      }

And here is the Model class to which I want to map this Json:

public class Model{

    private int                              _id;
    private String                           name;
    private int                              age
    private HashMap<String, String> columns;

    //Getters and Setter methods
}

So here, what i want is to get a map columns that contains keys "MEMO_TEXT","MEMO_LINK","MEMO_DOB","MEMO_USERNAME","MEMO_CATEGORY","MEMO_UID"

and rest of the properties in Json are mapped to their respective fields.

Is it possible to do this using ObjectMapper of Jackson Library?


Solution

  • You can use @JsonAnySetter to annotate a method to be called for "other" properties:

    @Test
    public void partial_binding() throws Exception {
        Model model = mapper.readValue(Resources.getResource("partial_binding.json"), Model.class);
        assertThat(model.name, equalTo("xyz"));
        assertThat(model.columns, hasEntry("MEMO_TEXT", "yyy"));
        assertThat(
                mapper.writeValueAsString(model),
                json(jsonObject()
                     .withProperty("Name", "xyz")
                     .withProperty("MEMO_TEXT", "yyy")
                     .withAnyOtherProperties()));
    }
    
    public static class Model {
        @JsonProperty
        private int _id;
        @JsonProperty("Name")
        private String name;
        @JsonProperty("Age")
        private int age;
        private HashMap<String, String> columns;
    
        @JsonAnyGetter
        public HashMap<String, String> getColumns() {
            return columns;
        }
    
        public void setColumns(HashMap<String, String> columns) {
            this.columns = columns;
        }
    
        @JsonAnySetter
        public void putColumn(String key, String value) {
            if (columns == null) columns = new HashMap<>();
            columns.put(key, value);
        }
    }
    

    Also, @JsonAnyGetter does "kind of the reverse", so this should serialize and deserialize the same way.