用杰克逊进行JSON反序列化

时间:2019-12-20 15:46:11

标签: java json jackson

我有一个看起来像这样的JSON:

{
  "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 ....}
  ]
}

records数组中的对象可以是不同的类型,但不会混合在一起。反序列化期间,可以忽略属性字段。

我正试图通过杰克逊将其反序列化到这个Java类中:

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

BaseObject的子类将具有必填字段,例如:

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

这是反序列化代码:

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);
    }

但这并不成功,我得到了例外:

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]]

任何建议将不胜感激。

1 个答案:

答案 0 :(得分:1)

方法constructCollectionLikeType中的第一个参数名称为collectionClass,因此它必须是集合类型:例如ArrayList

您需要使用constructParametricType方法。

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