如何使用Jackson将嵌套值从JSON数组解析为列表

时间:2019-04-23 15:53:26

标签: java json list parsing jackson

因此,我一直在寻找这个答案,但是我没有找到能反映我情况的解决方案。基本上,我的JSON结构如下:

{
    "count": 4424,
    "results": [
        {"id": 2718, "name": "fox", "location": "Omaha"}, 
        {"id": 2719, "name": "bear", "location": "Miami"}
        ...
        more objects containing an ID field
        ...
    ]
}

我希望能够解析出所有“ id”值并将它们存储在列表中,然后我将对其进行遍历以对其他端点进行后续的REST调用。如果我想要包含id字段的整个对象,我知道我可以创建一个新对象并创建一个自定义JSON反序列化器,但是由于它只是我想要的一个字段,因此感觉有点过头了。

我最初的想法是在自定义解串器中执行某些操作,例如:

List<String> idList = new ArrayList<String>();
JsonNode node = jp.getCodec().readTree(jp); // jp = JsonParser
JsonNode resultsNode = node.get("results");
resultsNode.forEach(result -> {
    JsonNode idNode = result.get("id");
    if (idNode != null) {
        String id = idNode.textValue().toUpperCase();
        idList.add(id);
    }
});

那是处理此问题的正确方法吗?如果不是,将这些ID值解析为列表的最佳/有效方式是什么?

此外,我在网上阅读有关尝试进行此类操作(列表可能包含1000多个ID)时可能想要进行缓存的信息,但是我不确定在这种情况下这意味着什么。谁能解释一下?

2 个答案:

答案 0 :(得分:1)

未经尝试,它看起来像一个JSON文件,它来自于将Sightings对象从类似的东西序列化

public AnimalSighting {
    public int id;
    public String name;
    public String location;
}
public Sightings {
    public int count;
    public ArrayList<AnimalSighting> results;
}

然后使用new ObjectMapper().readValue(file, Sightings.class);

即可进行反序列化

当然,这些类可以使用带有getter和setter的私有属性,然后可能需要一些注释(@ JsonCreator / @ JsonProperty / @ JsonGetter / @ JsonSetter,具体取决于您的工作),但一般原理仍然存在。 / p>

答案 1 :(得分:1)

如果只需要一部分JSON负载,则可以使用JsonPath库。您可以在下面找到如何使用它的示例:

import com.jayway.jsonpath.JsonPath;

import java.io.File;
import java.util.List;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        List<String> ids = JsonPath.read(jsonFile, "$.results.[*].id");
        System.out.println(ids);
    }
}

上面的代码显示:

[2718,2719]

使用Jackson,您可以根据需要创建尽可能小的POJO模型:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.util.List;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        List<Id> ids = mapper.readValue(jsonFile, Response.class).getIds();
        System.out.println(ids);
    }
}

class Response {

    private final List<Id> ids;

    @JsonCreator
    public Response(@JsonProperty("results") List<Id> ids) {
        this.ids = ids;
    }

    public List<Id> getIds() {
        return ids;
    }
}

class Id {

    private final String id;

    @JsonCreator
    public Id(@JsonProperty("id") String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }

    @Override
    public String toString() {
        return id;
    }
}

上面的代码显示:

[2718, 2719]
如果我们不想映射所有属性,则需要

FAIL_ON_UNKNOWN_PROPERTIES功能。它应该不会比使用自定义解串器的解决方案慢很多。

列表中的

1000+ JSON objects不是一个很大的数字,应该不成问题。您可以尝试为每种解决方案编写基准并比较结果。