Jackson 如何在不进行强制转换的情况下将 JsonNode 转换为 ArrayNode?

我正在将我的 JSON 库从 org.JSON 改为 Jackson,我想迁移以下代码:

JSONObject datasets = readJSON(new URL(DATASETS));
JSONArray datasetArray =  datasets.getJSONArray("datasets");

现在在杰克逊,我有以下几点:

ObjectMapper m = new ObjectMapper();
JsonNode datasets = m.readTree(new URL(DATASETS));
ArrayNode datasetArray = (ArrayNode)datasets.get("datasets");

但是我不喜欢那里的演员阵容,有没有 ClassCastException的可能性? 是否有一个方法等价于 org.json中的 getJSONArray,以便我有正确的错误处理,如果它不是一个数组?

279375 次浏览

在 org.json 中是否有一个等价于 getJSONArray 的方法,以便在它不是数组的情况下能够进行正确的错误处理?

它取决于您的输入; 也就是说,您从 URL 获取的内容。如果“数据集”属性的值是一个关联数组,而不是一个普通的数组,那么就会得到一个 ClassCastException

不过话说回来,旧版 还有的正确性取决于输入。在新版本抛出 ClassCastException的情况下,旧版本将抛出 JSONException。参考资料: http://www.json.org/javadoc/org/json/JSONObject.html#getJSONArray(java.lang.String)

是的,Jackson 手动解析器设计与其他库有很大不同。特别是,您将注意到,JsonNode具有大多数通常与其他 API 的数组节点关联的函数。因此,您不需要强制转换为 ArrayNode才能使用。这里有一个例子:

杰森:

{
"objects" : ["One", "Two", "Three"]
}

密码:

final String json = "{\"objects\" : [\"One\", \"Two\", \"Three\"]}";


final JsonNode arrNode = new ObjectMapper().readTree(json).get("objects");
if (arrNode.isArray()) {
for (final JsonNode objNode : arrNode) {
System.out.println(objNode);
}
}

产出:

“一”
“二”
“三”

请注意,在迭代之前,使用 isArray来验证节点实际上是一个数组。如果您对自己的数据结构绝对有信心,那么就不需要进行这种检查,但是如果您需要的话,它是可用的(这与大多数其他 JSON 库没有什么不同)。

我假设您最终希望通过迭代消耗 ArrayNode 中的数据。为此:

Iterator<JsonNode> iterator = datasets.withArray("datasets").elements();
while (iterator.hasNext())
System.out.print(iterator.next().toString() + " ");

或者如果你喜欢流和 lambda 函数:

import com.google.common.collect.Streams;
Streams.stream(datasets.withArray("datasets").elements())
.forEach( item -> System.out.print(item.toString()) )

在 Java8中你可以这样做:

import java.util.*;
import java.util.stream.*;


List<JsonNode> datasets = StreamSupport
.stream(obj.get("datasets").spliterator(), false)
.collect(Collectors.toList())

通过调用 JsonNode 的 iterator()方法获取迭代器,然后继续..。

  JsonNode array = datasets.get("datasets");


if (array.isArray()) {
Iterator<JsonNode> itr = array.iterator();
/* Set up a loop that makes a call to hasNext().
Have the loop iterate as long as hasNext() returns true.*/
while (itr.hasNext()) {
JsonNode item=itr.next();
// do something with array elements
}
}