我正在使用 Jackson 2.2 将一个非常大的 JSON 字符串读入 Java 对象。使用ObjectMapper
,我将所有内容读入内存并将 JSON 字符串转换为对象。这一切都发生在内存中,因此将整个 JSON 字符串加载到内存中并转换为对象。
如果有更高效的内存方式吗?即没有将整个 JSON 字符串加载到内存中,我应该仍然能够加载对象。
是的,您通常使用所谓的“流式处理”API 来迭代 JSON 令牌;并且一旦定位在您想要的值的第一个标记(JSON 对象的 START_OBJECT)上,使用数据绑定 API,传递读取器/解析器供它使用。这个细节取决于图书馆。我知道至少以下支持这种操作模式:
对于 Jackson,这里讨论了基本的 Streaming API 使用(例如);但是没有显示的一件事是,一旦您定位在正确的位置,如何绑定对象。所以假设 JSON 像:
{ "comment" : "...",
"values" : [
{ ... value object 1 ... },
{ ... value object 2. ... }
]
}
你可以这样做:
ObjectMapper mapper = new ObjectMapper();
JsonParser jp = mapper.getFactory().createJsonParser(jsonInput);
jp.nextToken(); // will return START_OBJECT, may want to verify
while (jp.nextValue() != null) { // 'nextValue' skips FIELD_NAME token, if any
String fieldName = jp.getCurrentName();
if ("values".equals(fieldName)) {
// yes, should now point to START_ARRAY
while (jp.nextToken() == JsonToken.START_OBJECT) {
ValueObject v = mapper.readValue(jp, ValueObject.class);
// process individual value in whatever way to you want to...
}
} else if ("comment".equals(fieldName)) {
// handle comment?
} // may use another else to catch unknown fields, if any
}
jp.close();
这应该让你一次只能绑定一个对象。