Skip to content
Advertisement

Jackson deserialize JSON into pojo with map property

Can somebody help me, how I can deserialize the following JSON, which I can not change? I am using Jackson for serialization.

{      
    "columns": [
      {
        "header": "Heading1",
      },
      {
        "header": "Heading2",
      }
    ],
    "rows": [
       "id": 1,
       "Heading1": {
          "value": "Value1"
       },
       "Heading2": {
          "value": "Value2"
       }
    ]
}

Columns can have unknown number of headers and their value eg. “Header1” is used in the rows array.

So far I have the following structure:

public class QueryResult {
   private ColumnConfig[] columns;
   private QueryResultRow[] rows;
}
public class ColumnConfig {
   private String header;
}
public class QueryResultRow {
   private int id;
   private Map<String, CellValue> values;
}
public class CellValue{
   private String value;
}

The problem is that the Map is empty when I deserialize into QueryResult; I read about TypeReference but I do not know how I can specify a TypeReference<HashMap<String,CellValue>> for the property values in QueryResultRow.

Edit:

My ObjectMapper code is the following:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
String queryResultString = loadQuery(queryPath);
        QueryResult result = mapper.readValue(queryResultString, QueryResult.class);

The content of queryResultString is the JSON above.

Advertisement

Answer

First problem is your JSON is invalid. I assume it should be something like this,

{
  "columns": [
    {
      "header": "Heading1"
    },
    {
      "header": "Heading2"
    }
  ],
  "rows": [
    {
      "id": 1,
      "Heading1": {
        "value": "Value1"
      },
      "Heading2": {
        "value": "Value2"
      }
    }
  ]
}

Then answer is quite straightforward. You need to change your QueryResultRow as follows,

class QueryResultRow {
    private int id;
    private Map<String, CellValue> values = new HashMap<>();
    
    @JsonAnySetter
    public void addValues(String k, CellValue v) {
        values.put(k, v);
    }
}

Then I think you should good to go.

Here is a complete working example,

public class Main {
    public static void main(String[] args) throws IOException {
        String s = "{"columns":[{"header":"Heading1"},{"header":"Heading2"}],"rows":[{"id":1,"Heading1":{"value":"Value1"},"Heading2":{"value":"Value2"}}]}";
        
        ObjectMapper om = new ObjectMapper();
        QueryResult queryResult = om.readValue(s, QueryResult.class);

        System.out.println(queryResult);
    }
}

@Getter
@Setter
@ToString
class QueryResult {
    private ColumnConfig[] columns;
    private QueryResultRow[] rows;
}

@Getter
@Setter
@ToString
class ColumnConfig {
    private String header;
}

@Getter
@Setter
@ToString
class QueryResultRow {
    private int id;
    private Map<String, CellValue> values = new HashMap<>();
    
    @JsonAnySetter
    public void addValues(String k, CellValue v) {
        values.put(k, v);
    }
}

@Getter
@Setter
@ToString
class CellValue{
    private String value;
}

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement