Джексон, как преобразовать 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
?
Есть ли метод, эквивалентный getJSONArray
в org.json
, так что у меня есть правильная обработка ошибок, если это не массив?
Ответы
Ответ 1
Да, дизайн ручного парсера 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);
}
}
Вывод:
"One"
"Two" "Три"
Обратите внимание на использование isArray
, чтобы убедиться, что node на самом деле является массивом перед итерацией. Проверка не нужна, если вы абсолютно уверены в своей структуре данных, но ее доступный вам нужен (и это ничем не отличается от большинства других библиотек JSON).
Ответ 2
Есть ли метод, эквивалентный getJSONArray в org.json, так что у меня есть правильная обработка ошибок, если он не является массивом?
Это зависит от вашего ввода; т.е. материал, который вы извлекаете из URL-адреса. Если значение атрибута "наборы данных" является ассоциативным массивом, а не простым массивом, вы получите ClassCastException
.
Но опять же, правильность вашей старой версии также зависит от ввода. В ситуации, когда ваша новая версия бросает ClassCastException
, старая версия будет бросать JSONException
. Ссылка: http://www.json.org/javadoc/org/json/JSONObject.html#getJSONArray(java.lang.String)
Ответ 3
Я бы предположил, что в конце дня вы хотите использовать данные в ArrayNode, итерации. Для этого:
Iterator<JsonNode> iterator = datasets.withArray("datasets").elements();
while (iterator.hasNext())
System.out.print(iterator.next().toString() + " ");
или если вы находитесь в потоках и лямбда-функциях:
import com.google.common.collect.Streams;
Streams.stream(datasets.withArray("datasets").elements())
.forEach( item -> System.out.print(item.toString()) )