使用Jackson流式api for JSON,我如何循环访问对象? [英] Using the Jackson streaming api for JSON, how do I while loop through an object?

查看:165
本文介绍了使用Jackson流式api for JSON,我如何循环访问对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

    ObjectMapper map = new ObjectMapper(); //for later inner object data binding
    JsonParser p = map.getFactory().createParser(new File("test.json"));
    //start the tokenizing of object
    p.nextToken();
    //loop until the end object is found, simultaneously incrementing loop
    while (p.nextToken() != JsonToken.END_OBJECT) {
        //...
    }
    p.close(); 

(请注意,我可能有更好的方法来做我想做的事情,我欢迎关于如何更好地做到这一点的任何建议,但也请告诉我,如果我现有的技术是可行的)

(note, there is probably a better way to do what I am trying to do here and I welcome any advice on how to do this better, but please also tell me if my current technique is possible)

这是我目前的代码,并没有进一步,因为我意识到了一个缺陷。这段代码取自杰克逊流媒体API教程,我试图让它适应我的项目。

This is the code I currently have and have not gone any further because I realized a flaw. This code was taken from a Jackson streaming API tutorial and I am trying to adapt it to my project.

我要做的是循环一个对象的标记在从对象开始到结束的json文件中。但是,此json文件包含许多内部对象,并且循环可能会在内部对象的END_OBJECT处过早结束。

What I am trying to do is loop through the tokens of an object in a json file from the start of the object to its end. However, this json file contains many inner objects, and the loop may end prematurely at the END_OBJECT of an inner object.

我当时的想法是,也许我可以尝试更明确地使while循环结束:仅当它遇到其START_OBJECT的相应END_OBJECT时。我查看了杰克逊文档(在JsonParser和JsonToken),但我无法弄清楚如何以编程方式执行此操作。

What I thought then was, maybe I could try to make the while loop end more specifically: only when it encounters the corresponding END_OBJECT of its START_OBJECT. I have looked in the Jackson docs (at JsonParser and JsonToken) but I cannot figure out how I would do this programmatically.

我的问题是,如何编写仅循环通过一个对象的while循环?如何唯一地定义对象的结尾?我考虑将初始起始对象JsonToken存储在内存中,但我不确定如何将它与结束对象令牌进行比较以查看两者是否完全相关。杰克逊的文档对此没有太多的描述,或者我太可爱和天真。

My question then is, how do I write a while loop that loops through one object only? How do I uniquely define the end of the object? I thought about storing the initial start object JsonToken in memory but I am not sure how I could compare it to the end object token to see if the two are related at all. The Jackson docs aren't too descriptive on this or maybe I am too wishful and naive.

我正在使用映射器,因为我将在此方法中混合使用数据绑定和流式传输。我只需要数据绑定内部对象。

I am using a mapper because I will be doing a mix of data binding and streaming in this method. I only need to data bind the inner objects.

第一个对象包含一个数组,decks

The first object contains an array, "decks"

内部对象包含一个卡片组(也是一个数组)。

The inner object contains a deck's cards (also an array).

我将是数据绑定单卡(因为我已经看了很多,但没有找到一种更简单的数据方式绑定内部对象(卡片),同时保留他们来自的套牌的一些信息。)

I will be data binding single cards (as I have looked extensively but have not found an easier way to data bind inner objects (cards) while retaining some information of the "deck" they came from).

推荐答案

具体关于你的方式要做到这一点,最简单的通用解决方案是计算遇到的START_OBJECT与END_OBJECT(CS类中的相同练习,知道表达式是否包含正确数量的开括号和右括号)。所以你的代码看起来像:

Specifically regarding the way you do it, the simplest general solution would be counting the START_OBJECT encountered vs the END_OBJECT (same exercise in CS classes of knowing if an expression contains the correct number of opening and closing parenthesis). So your code would look like:

ObjectMapper map = new ObjectMapper(); //for later inner object data binding
JsonParser p = map.getFactory().createParser(new File("test.json"));
//start the tokenizing of object
p.nextToken();
// Assuming the first token you encounter is the START_OBJECT, otherwise start from 0.
int startEndCounter = 1;
//loop until the end object is found, simultaneously incrementing loop
while (startEndCounter != 0) {
    //...
    if (p.nextToken() == JsonToken.STAR_OBJECT) {
        startEndCounter++;    
    } else if (p.nextToken() == JsonToken.END_OBJECT) {
        startEndCounter--;    
    }
}
p.close();

使用解析器读取对象的Jackson方式:

And the Jackson way to read an object using the parser:

Card card = mapper.readValue(jp, Card.class);

以下是 fasterxml wiki ,它将在每次迭代时读取一个Card对象:

Here's a variation of an example from the fasterxml wiki, which will read a Card object on each iteration:

JsonParser jp = map.getFactory().createParser(new File("test.json"));
// advance stream to START_ARRAY first:
jp.nextToken();
// and then each time, advance to opening START_OBJECT
while (jp.nextToken() == JsonToken.START_OBJECT)) {
Card card = mapper.readValue(jp, Card.class);
   // process
   // after binding, stream points to closing END_OBJECT
}

这篇关于使用Jackson流式api for JSON,我如何循环访问对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆