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
の可能性はありますか? org.json
にgetJSONArray
に相当するメソッドがあり、配列ではない場合に適切なエラー処理を行うことができますか?
はい、ジャクソンの手動パーサーの設計は他のライブラリとはまったく異なります。特に、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);
}
}
出力:
"1"
"二"
"三"
反復する前に、ノードが実際に配列であることを確認するisArray
の使用に注意してください。データ構造に完全に自信がある場合、このチェックは不要ですが、必要に応じて使用できます(これは他のほとんどのJSONライブラリと同じです)。
Org.jsonにgetJSONArrayと同等のメソッドがあり、配列ではない場合に適切なエラー処理を行うことができますか?
入力に依存します。つまり、URLから取得したもの。 「datasets」属性の値がプレーン配列ではなく連想配列の場合、ClassCastException
を取得します。
ただし、古いバージョンalsoの正確さは入力に依存します。新しいバージョンがClassCastException
をスローする状況では、古いバージョンはJSONException
をスローします。リファレンス: http://www.json.org/javadoc/org/json/JSONObject.html#getJSONArray(Java.lang.String)
一日の終わりに、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()) )