Java Jackson:解析三级JSON动态对象结构

时间:2018-04-06 15:37:57

标签: java json jackson objectmapper

我试图使用Java Jackson ObjectMapper来解析带有动态密钥的三级JSON对象结构。我尝试了以下方法:

public class AssetsPushManifest {
    private Map<String, List<Asset>> manifest = new HashMap<>();

    public void addPushManifest(Resource manifestResource) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Map<String, Asset>> manifestData = mapper.readValue(manifestResource.getInputStream(), new TypeReference<Map<String, Map<String, Asset>>>() {});
        for (String requestedPathName : manifestData.keySet()) {
            if (!this.manifest.containsKey(requestedPathName)) {
                this.manifest.put(requestedPathName, new LinkedList());
            }
            List<Asset> requestedPath = this.manifest.get(requestedPathName);

            for (String servePath : manifestData.get(requestedPathName).keySet()) {
                Asset asset = manifestData.get(requestedPathName).get(servePath);
                asset.path = servePath;
                requestedPath.add(asset);
            }
        }

        ...
    }

    public class Asset {
        public String path;
        public String type;
        public Integer weight;
    }
}

解析这个:

{
  "theme/test-theme/index.html": {
    "theme/test-theme/somestyling.css": {
      "type": "document",
      "weight": 1
    }
  }
}

但它不会起作用,为什么呢?为什么?太多级了吗? (这里仍然是Java初学者)

最终目标是将上面的几个JSON结构解析为Map&gt;等结构。所以任何其他方式也可以。

1 个答案:

答案 0 :(得分:0)

我会以不同的方式解决这个问题:将json解析为一个地图:如果你给Jackson一个地图作为类型引用,它会将JSON反序列化为多级地图:

`Map<String, Object> manifestData = mapper.readValue(manifestResource.getInputStream(), Map.class);`

既然json解析障碍已经过去了,那么通过查询地图来构造Asset的实例会更容易。我会通过向Asset类添加构造函数来实现:

public Asset(Map<String, Object> manifestData) { 
    Map<String, Object> assetData = (Map<String, Object>)manifestData.values().iterator().next();  // get the single value of the map
    this.path = assetData.keySet().iterator().next();
    this.type = assetData.get("type"); 
    this.weight = assetData.get("weight");
}