Подтвердить что ты не робот

Джексон, как преобразовать 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, так что у меня есть правильная обработка ошибок, если это не массив?

4b9b3361

Ответ 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()) )