杰克逊如何在不投射的情况下将JsonNode转换为ArrayNode?

时间:2013-05-28 09:14:36

标签: java json jackson

我正在将我的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的可能性? 在getJSONArray中是否存在等同于org.json的方法,以便在不是数组的情况下进行适当的错误处理?

3 个答案:

答案 0 :(得分:212)

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

JSON:

{
    "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库没有区别)。

答案 1 :(得分:1)

  

是否有一个与org.json中的getJSONArray等效的方法,以便在没有数组的情况下进行适当的错误处理?

这取决于你的输入;即你从URL获取的东西。如果“datasets”属性的值是关联数组而不是普通数组,则会得到ClassCastException

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

答案 2 :(得分:0)

我想在一天结束时要通过迭代来消耗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()) )