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

Kon*_*ner 101 java json jackson

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

JSONObject datasets = readJSON(new URL(DATASETS));
JSONArray datasetArray =  datasets.getJSONArray("datasets");
Run Code Online (Sandbox Code Playgroud)

现在在杰克逊我有以下内容:

ObjectMapper m = new ObjectMapper();
JsonNode datasets = m.readTree(new URL(DATASETS));      
ArrayNode datasetArray = (ArrayNode)datasets.get("datasets");
Run Code Online (Sandbox Code Playgroud)

但是我不喜欢那里的演员,是否有可能ClassCastException?是否有一个等效的方法getJSONArray,org.json以便我有适当的错误处理,以防它不是一个数组?

Per*_*ion 225

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

JSON:

{
    "objects" : ["One", "Two", "Three"]
}
Run Code Online (Sandbox Code Playgroud)

码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

"一"
"两"
"三"

注意isArray在迭代之前用于验证节点实际上是一个数组.如果您对数据结构非常有信心,则无需进行检查,但如果您需要它,则可以使用它(这与大多数其他JSON库没有区别).

  • 你节省了我几个小时。谢谢! (2认同)
  • @AnthonyVinay 使变量不可变;许多程序员认为这是一种很好的编码实践。另请参阅[此](https://softwareengineering.stackexchange.com/questions/98691/excessive-use-final-keyword-in-java)讨论! (2认同)

Ori*_*ski 15

在 Java 8 中,你可以这样做:

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

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


Wil*_*mer 5

我假设最终您希望通过迭代来使用 ArrayNode 中的数据。为了那个原因:

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

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

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