NickJ
NickJ

Reputation: 9559

JSON De-serialisation with jackson

I have JSON which looks like this:

{
  "totalSize": 11,
  "done": true,
  "records": [
    {
      "attributes": {
        "type": "Team_Member",
        "url": "/services/data/Team_Member/xxxx"
      },
      "Age": 48,
      "Birth_Date": "1971-05-17",
      "Business": null,
      "Citizenship": null,
      "Country": "UK",
      ...other fields...
    },
    { other records ....}
  ]
}

The objects in the records array can be of different types, but will not be mixed. During de-serialisation, the attributes field can be ignored.

I am trying to de-serialize it with jackson into this Java class:

@lombok.Data
public class QueryResult<C extends BaseObject> {
    private int totalSize;
    private boolean done;
    private List<C> records;
}

And sub-classses of BaseObject will have the required fields, example:

public class TeamMember extends BaseObject {
    public int Age;
    public Date Birth_Date;
    //etc...
}

Here is the de-serialization code:

public <C extends BaseObject> QueryResult<C> doQuery(Class<C> baseObjectClass) {

    String json = ...get json from somewhere
    ObjectMapper mapper = new ObjectMapper();
    try {
        JavaType type = mapper.getTypeFactory().constructCollectionLikeType(QueryResult.class, baseObjectClass);
        return mapper.readValue(json, type);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

But this is not successful, I get the exception:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot find a Value deserializer for type [collection-like type; class com.foo.QueryResult, contains [simple type, class com.foo.TeamMember]]

Any suggestion would be appreciated.

Upvotes: 1

Views: 267

Answers (1)

Michał Ziober
Michał Ziober

Reputation: 38655

First parameter name in method constructCollectionLikeType is collectionClass so it must be a collection type: ArrayList, for example.

You need to use constructParametricType method.

JavaType queryType = mapper.getTypeFactory().constructParametricType(QueryResult.class, TeamMember.class);
QueryResult<TeamMember> queryResult = mapper.readValue(jsonFile, queryType);

Upvotes: 1

Related Questions