HOWTO · Java

Java での JSON 配列の処理

この記事では、JSON フレームワーク、その構造、データ型、および Java での使用について説明します。

このページの内容

JavaでファイルからJSON配列を読み込むには、JSON.simpleなどのJSONパーサーをプロジェクトに追加し、ファイルを解析して、得られた配列を走査します。Javaの標準ライブラリには、汎用的なJSONパーサーは含まれていません。JSON.simpleは外部依存ライブラリなので、プロジェクトで使用しているビルドツールや依存関係管理ツールから追加してください。

JSON.simpleには複数のリリースとAPI系統があります。以下の例では org.json.simple のAPI系統を扱います。使用する前にリリースを選び、そのリリースのドキュメントで依存関係の指定方法、パーサーAPI、値の型を確認してください。ここでは特定のリリースやビルドツールを前提としていません。選択したリリースでパッケージ名やメソッドのシグネチャが異なる場合は、別のリリース向けの依存関係指定をそのまま使わず、ドキュメントに合わせて例を調整してください。

JavaでJSON配列を扱う

JSON(JavaScript Object Notation)は、オブジェクト、配列、文字列、数値、真偽値、nullを使ってデータを表します。JavaのコードでJSONテキストを扱える値に変換するには、パーサーが必要です。JSON.simpleは、その解析に使えるライブラリの1つです。

配列は角括弧で囲まれた順序付きの並びです。オブジェクトは波括弧で囲まれた、名前付きの値の集合です。配列とオブジェクトは入れ子にできます。そのため、ファイルの先頭が配列で、その各要素がオブジェクトであり、各オブジェクトにさらに配列やオブジェクトが含まれる場合もあります。

JavaのJSONオブジェクトとJSON配列

オブジェクトでは文字列のキーに値を対応付け、キーと値の間をコロンで区切り、各項目をカンマで区切ります。配列では値を位置によって並べ、カンマで区切ります。たとえば、インラインのJSON値 [1, "abc", {"name":"xyz"}] は、数値、文字列、オブジェクトを含む配列です。このオブジェクトには name というキーがあり、その値は文字列です。

この例で使うファイルの最上位には、オブジェクトが1つ入った配列があります。そのオブジェクトには文字列、数値、2つの入れ子の配列、そして入れ子のオブジェクトが含まれます。

[{"name":"MMN","roll":24,"marks":[91,95,97,97,94],"parents":{"name":"IMT","mobile":"1234567890"},"hobbies":["sports","reading","music"],"others":["A",1]}]

値を取り出すときはデータの形を把握しておく必要があります。name、roll、parentsを読み取るコードは、それらのキーが存在し、想定したJSONの型の値を持つことを前提とします。管理できない外部入力を扱う場合は、特定のJava型として処理する前に各値を検証してください。

JSON.simpleを使ってJavaでファイルからJSON配列を読み込む

JSON.simpleは、プロジェクトの依存関係管理ツールから追加してください。選択したリリースについてドキュメントに記載されたアーティファクト座標を使います。ここでは特定のリリースやビルドツールを前提としていないため、座標は指定しません。org.json.simple のパッケージ群は外部ライブラリです。対応するライブラリをクラスパスに含めなければ、Java標準ライブラリだけの環境では、そのインポートやパーサー呼び出しを実行できません。

互換性のあるJSON.simpleリリースを使うプロジェクトでは、解析処理の概念的な形は new JSONParser().parse(reader) です。正確なパーサーAPIと返されるコレクションの型は、そのリリースのドキュメントで確認してください。以下の例ではその次の段階、つまりパーサーが生成したJavaのコレクション構造を走査する処理に焦点を当てます。値は上のサンプルファイルに合わせてあり、Java標準ライブラリのコレクションだけを使うため、単独で実行できます。

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class JSONArrayTraversal {
  public static void main(String[] args) {
    Map<String, Object> parents = new LinkedHashMap<>();
    parents.put("name", "IMT");
    parents.put("mobile", "1234567890");

    Map<String, Object> record = new LinkedHashMap<>();
    record.put("name", "MMN");
    record.put("roll", 24);
    record.put("marks", Arrays.asList(91, 95, 97, 97, 94));
    record.put("parents", parents);
    record.put("hobbies", Arrays.asList("sports", "reading", "music"));
    record.put("others", Arrays.asList("A", 1));
    List<Map<String, Object>> records = Arrays.asList(record);

    for (Map<String, Object> item : records) {
      System.out.println("Name: " + item.get("name"));
      System.out.println("Roll: " + item.get("roll"));
      System.out.println("Marks: " + item.get("marks"));
      System.out.println("Hobbies: " + item.get("hobbies"));
      Map<?, ?> parent = (Map<?, ?>) item.get("parents");
      System.out.println("Parent's Name: " + parent.get("name")
          + ", Mobile: " + parent.get("mobile"));
      System.out.println("Others: " + item.get("others"));
    }
  }
}
Name: MMN
Roll: 24
Marks: [91, 95, 97, 97, 94]
Hobbies: [sports, reading, music]
Parent's Name: IMT, Mobile: 1234567890
Others: [A, 1]

アプリケーションでは、選択したJSON.simpleパーサーが返す値を、そのリリースのコレクション型に合わせた走査コードに渡します。ここでは records が解析後の最上位配列に相当します。キャストやフィールドの検索方法はサンプルのスキーマを前提としているため、入力によって形が変わる場合は、型を前提に処理する前に配列の各要素とフィールドを検証してください。解析中はリーダーを開いたままにし、解析後に閉じます。解析に失敗した場合も同様です。ファイルへのアクセスや解析の失敗は、選択したリリースのドキュメントに記載された動作とアプリケーションの要件に沿って処理してください。この走査処理をファイル入力につなぐときは、実行環境で実際に存在し、読み取り可能なパスを指定してください。

結論

JSON配列は順序付きの並びであり、JSONオブジェクトはキーに名前付きの値を対応付けます。Javaでファイルから配列を読み込むには、JSON.simpleなどの外部パーサーを使い、選択したリリースのドキュメントに従って依存関係をプロジェクトに追加してから、入力スキーマに合わせて解析後の構造を走査します。キャストや変換に頼る前に、選択したリリースのAPIと数値の値型を確認してください。