首页 > 解决方案 > JSON反序列化与杰克逊

问题描述

我有如下所示的 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 ....}
  ]
}

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

我正在尝试用jackson将它反序列化到这个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]]

任何建议将不胜感激。

标签: javajsonjackson

解决方案


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

您需要使用constructParametricType方法。

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

推荐阅读