使用Jackson来解析一组Json对象

Pro*_*000 13 json jackson

我有一个包含json对象数组的文件:

[{"test1":"abc"},{"test2":[1,2,3]}]

我希望使用Jackson的JsonParser从这个文件中获取一个输入流,并且在每次调用.next()时,我希望它从数组中返回一个对象,直到它用完对象或失败.

这可能吗?

使用案例:我有一个大型文件,其中json数组中填充了大量具有不同模式的对象.我希望一次获得一个对象,以避免将所有内容加载到内存中.

编辑:

我完全忘了提.我的输入是随着时间的推移而添加的字符串.它随着时间的推移逐渐积累json.我希望能够通过对象从字符串中删除已解析的对象来解析它.

但我想这没关系!只要jsonParser将索引返回到字符串中,我就可以手动执行此操作.

Ian*_*rts 37

是的,您可以使用以下方法实现这种部分流 - 部分 - 树模型处理样式ObjectMapper:

ObjectMapper mapper = new ObjectMapper();
JsonParser parser = mapper.getFactory().createParser(new File(...));
if(parser.nextToken() != JsonToken.START_ARRAY) {
  throw new IllegalStateException("Expected an array");
}
while(parser.nextToken() == JsonToken.START_OBJECT) {
  // read everything from this START_OBJECT to the matching END_OBJECT
  // and return it as a tree model ObjectNode
  ObjectNode node = mapper.readTree(parser);

  // do whatever you need to do with this object
}

parser.close();
Run Code Online (Sandbox Code Playgroud)

  • 嘿伊恩,经过将近两年的时间,这段代码实际上仍然可以工作并节省了我的一天.只是试图确认,每次mapper执行读取树直到END_OBJECT标记匹配它开始的位置时,解析器的"Cursor"也会移动到那里?所以,如果我在while循环之后立即执行另一个`parser.nextToken()`,我应该在读取之后读取下一个对象,对吗? (2认同)
  • @JamesJiang正确.给定位于`START_OBJECT`的解析器的`readTree`将使用来自解析器的事件,直到它到达匹配的`END_OBJECT`并且将解析器放在那里. (2认同)

pgi*_*cek 12

您正在寻找的是Jackson Streaming API.这是一个使用Jackson Streaming API的代码片段,可以帮助您实现所需.

JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createJsonParser(new File(yourPathToFile));

JsonToken token = parser.nextToken();
if (token == null) {
    // return or throw exception
}

// the first token is supposed to be the start of array '['
if (!JsonToken.START_ARRAY.equals(token)) {
    // return or throw exception
}

// iterate through the content of the array
while (true) {

    token = parser.nextToken();
    if (!JsonToken.START_OBJECT.equals(token)) {
        break;
    }
    if (token == null) {
        break;
    }

    // parse your objects by means of parser.getXxxValue() and/or other parser's methods

}
Run Code Online (Sandbox Code Playgroud)


sta*_*ker 5

此示例直接从流中读取自定义对象:

源是一个 java.io.File

ObjectMapper mapper = new ObjectMapper();
JsonParser parser = mapper.getFactory().createParser( source );
if ( parser.nextToken() != JsonToken.START_ARRAY ) {
    throw new Exception( "no array" );
}
while ( parser.nextToken() == JsonToken.START_OBJECT ) {
    CustomObj custom = mapper.readValue( parser, CustomObj.class );
    System.out.println( "" + custom );
}
Run Code Online (Sandbox Code Playgroud)