'Jackson how to transform JsonNode to ArrayNode without casting?

I am changing my JSON library from org.json to Jackson and I want to migrate the following code:

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

Now in Jackson I have the following:

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

However I don't like the cast there, is there the possibility for a ClassCastException? Is there a method equivalent to getJSONArray in org.json so that I have proper error handling in case it isn't an array?



Solution 1:[1]

In Java 8 you can do it like this:

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

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

Solution 2:[2]

I would assume at the end of the day you want to consume the data in the ArrayNode by iterating it. For that:

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

or if you're into streams and lambda functions:

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

Solution 3:[3]

Is there a method equivalent to getJSONArray in org.json so that I have proper error handling in case it isn't an array?

It depends on your input; i.e. the stuff you fetch from the URL. If the value of the "datasets" attribute is an associative array rather than a plain array, you will get a ClassCastException.

But then again, the correctness of your old version also depends on the input. In the situation where your new version throws a ClassCastException, the old version will throw JSONException. Reference: http://www.json.org/javadoc/org/json/JSONObject.html#getJSONArray(java.lang.String)

Solution 4:[4]

Obtain an iterator by calling the JsonNode's iterator() method, and go on...

  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
      }
  }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Wildhammer
Solution 3
Solution 4 ucMedia