Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 699
Puneetr90 Avatar asked May 07 '15 12:05

Puneetr90


People also ask

How do I read JSON file with ObjectMapper?

Read Object From JSON via URL ObjectMapper objectMapper = new ObjectMapper(); URL url = new URL("file:data/car. json"); Car car = objectMapper. readValue(url, Car. class);

How do I convert a JSON list to Jackson?

We can convert a List to JSON array using the writeValueAsString() method of ObjectMapper class and this method can be used to serialize any Java value as a String.

What is the use of Jackson ObjectMapper?

ObjectMapper is the main actor class of Jackson library. ObjectMapper class ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs (Plain Old Java Objects), or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.


2 Answers

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.

like image 71
araqnid Avatar answered Oct 12 '22 23:10

araqnid


One of several ways to achieve what you want is to add a constructor:

@JsonCreator
public Model(Map<String, Object> fields) {
    this._id = (int) fields.remove("_id");
    this.name = (String) fields.remove("Name");
    this.age = (int) fields.remove("Age");
    this.columns = new HashMap<String, String>();
    for (Entry<String, Object> column : fields.entrySet()) {
        columns.put(column.getKey(), column.getValue().toString());
    }
}

Be aware that if you serialize it back to JSON the structure will be diffrent than the initial one.

like image 42
Lukasz Wiktor Avatar answered Oct 13 '22 00:10

Lukasz Wiktor