繁体   English   中英

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

[英]How to Parse Nested Value Into List From JSON Array Using 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)时可能想要进行缓存的信息,但是我不确定在这种情况下这意味着什么。 有人能解释吗?

无需尝试,它看起来像一个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);反序列化new ObjectMapper().readValue(file, Sightings.class);

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

如果只需要一部分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 ,数量不多,应该不成问题。 您可以尝试为每个解决方案编写基准并比较结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM