Java で相対パスから JSON ファイルを読み込む方法

JavaBeginner
オンラインで実践に進む

はじめに

現代の Java 開発において、JSON(JavaScript Object Notation)の扱いは基本的なスキルです。JSON は、その人間が読みやすい形式と機械による解析の容易さから、Web アプリケーションや API におけるデータ交換の事実上の標準となっています。

このチュートリアルでは、Java アプリケーションで相対パスから JSON ファイルを読み取り、解析するための包括的なガイドを提供します。必要な依存関係を持つ Maven プロジェクトのセットアップ方法、JSON ファイルの作成と構造化、相対パスからの読み取り、そして複雑なネストされたデータを含むコンテンツの解析方法を学びます。

この実験(Lab)の終わりには、Java プロジェクト内で JSON データを管理することに習熟しているでしょう。これは、Web サービス、API、または設定ファイルを扱うあらゆる開発者にとって重要なスキルです。

プロジェクトのセットアップと JSON ファイルの作成

JSON ファイルを読み込む前に、プロジェクト環境をセットアップし、ファイル自体を作成する必要があります。この実験(Lab)では、Apache Maven を使用してプロジェクトの依存関係を管理します。初期セットアップにより、標準的な Maven プロジェクト構造が既に作成されています。

プロジェクト構造の理解

左側の WebIDE ファイルエクスプローラーで、~/project ディレクトリ内に以下の構造が表示されます。

  • pom.xml: Maven の Project Object Model ファイルです。プロジェクトの依存関係とビルド構成を定義します。
  • src/main/java: Java ソースコード用のディレクトリです。
  • src/main/resources: 設定ファイルやデータファイルなどのリソースファイル用のディレクトリです。

pom.xml ファイルは、Java で JSON を扱うための一般的な選択肢である org.json ライブラリが含まれるように事前に構成されています。

JSON データファイルの作成

次に、後続のステップで読み込む JSON ファイルを作成しましょう。

  1. WebIDE ファイルエクスプローラーで、src/main/resources ディレクトリに移動します。
  2. resources フォルダを右クリックし、「新規ファイル」を選択します。
  3. ファイル名を data.json とします。
  4. 新しく作成された data.json ファイルを開き、以下のコンテンツを追加します。
{
  "name": "John Doe",
  "age": 28,
  "email": "john.doe@example.com",
  "isEmployed": true,
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  },
  "skills": ["Java", "SQL", "JavaScript"]
}

この JSON ファイルはユーザープロファイルを表しています。単純なキーと値のペア("name": "John Doe" など)、ネストされたオブジェクト(address)、および文字列の配列(skills)が含まれています。コンテンツを貼り付けたら、ファイルを保存してください。

これで、プロジェクトのセットアップと JSON データファイルの作成が完了しました。次のステップでは、このファイルを読み込んで解析する Java コードを記述します。

シンプルな JSON ファイルの読み込みと解析

JSON ファイルが準備できたので、それを読み込む Java プログラムを作成できます。ここでは、アプリケーションがさまざまな環境で移植可能であることを保証するための一般的な手法である相対パスを使用します。

相対パスの理解

相対パスは、現在の作業ディレクトリから指定されます。ターミナルから Maven プロジェクトを実行する場合、作業ディレクトリは通常プロジェクトのルートフォルダであり、この場合は ~/project です。したがって、JSON ファイルへの相対パスは src/main/resources/data.json となります。

Java JSON リーダーの作成

ファイルを読み込むための Java クラスを作成しましょう。

  1. WebIDE ファイルエクスプローラーで、src/main/java/com/labex に移動します。
  2. com/labex フォルダを右クリックし、「新規ファイル」を選択します。
  3. ファイル名を JsonReader.java とします。
  4. ファイルを開き、以下の Java コードを追加します。
package com.labex;

import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonReader {
    public static void main(String[] args) {
        try {
            // JSON ファイルへの相対パスを定義します
            String filePath = "src/main/resources/data.json";
            System.out.println("Reading file from: " + filePath);

            // ファイルの内容を文字列に読み込みます
            String content = new String(Files.readAllBytes(Paths.get(filePath)));

            // 文字列コンテンツから JSONObject を作成します
            JSONObject jsonObject = new JSONObject(content);

            // シンプルなキーの値にアクセスして表示します
            String name = jsonObject.getString("name");
            int age = jsonObject.getInt("age");
            boolean isEmployed = jsonObject.getBoolean("isEmployed");

            System.out.println("\n--- Parsed JSON Data ---");
            System.out.println("Name: " + name);
            System.out.println("Age: " + age);
            System.out.println("Is Employed: " + isEmployed);

        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Error parsing JSON: " + e.getMessage());
        }
    }
}

コードの説明

  • package com.labex;: 標準的な Java の規約に従い、このクラスが com.labex パッケージに属することを宣言します。
  • String filePath = "src/main/resources/data.json";: ファイルへの相対パスを定義します。
  • Files.readAllBytes(Paths.get(filePath)): ファイルの全内容をバイト配列に読み込み、それを String に変換します。
  • new JSONObject(content): JSON データを含む文字列を JSONObject に解析します。
  • jsonObject.getString("name"): キー "name" に関連付けられた文字列値を取得します。getInt()getBoolean() のような同様のメソッドが他のデータ型に使用されます。

プログラムのコンパイルと実行

次に、Maven を使用してコードをコンパイルして実行しましょう。

  1. WebIDE でターミナルを開きます。
  2. 以下のコマンドを実行して、クラスをコンパイルして実行します。
mvn compile exec:java -Dexec.mainClass="com.labex.JsonReader"

ターミナルに以下の出力が表示されるはずです。

Reading file from: src/main/resources/data.json

--- Parsed JSON Data ---
Name: John Doe
Age: 28
Is Employed: true

この出力は、プログラムが data.json ファイルを相対パスから正常に読み込み、基本的なプロパティを解析したことを確認します。

複雑な JSON データの取り扱い

実際の JSON データには、オブジェクト内のオブジェクトや値の配列など、ネストされた構造が含まれることがよくあります。data.json ファイルには、ネストされた address オブジェクトと skills 配列が含まれています。これらの複雑な構造を解析するために、知識を拡張しましょう。

複雑な JSON パーサーの作成

JSON ファイルのもっと複雑な部分を解析するデモンストレーションのために、新しいクラスを作成します。

  1. WebIDE ファイルエクスプローラーで、src/main/java/com/labex に移動します。
  2. ComplexJsonParser.java という名前の新しいファイルを作成します。
  3. ファイルに以下のコードを追加します。
package com.labex;

import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ComplexJsonParser {
    public static void main(String[] args) {
        try {
            String filePath = "src/main/resources/data.json";
            String content = new String(Files.readAllBytes(Paths.get(filePath)));
            JSONObject person = new JSONObject(content);

            System.out.println("--- Parsing Complex JSON Data ---");

            // ネストされた 'address' オブジェクトにアクセスします
            JSONObject address = person.getJSONObject("address");
            String street = address.getString("street");
            String city = address.getString("city");

            System.out.println("\nAddress:");
            System.out.println("  Street: " + street);
            System.out.println("  City: " + city);

            // 'skills' 配列にアクセスします
            JSONArray skills = person.getJSONArray("skills");
            System.out.println("\nSkills:");
            for (int i = 0; i < skills.length(); i++) {
                String skill = skills.getString(i);
                System.out.println("  - " + skill);
            }

        } catch (IOException e) {
            System.out.println("Error reading file: " + e.getMessage());
        } catch (Exception e) {
            System.out.println("Error parsing JSON: " + e.getMessage());
        }
    }
}

コードの説明

  • person.getJSONObject("address"): このメソッドは、キー "address" に関連付けられたネストされた JSON オブジェクトを取得します。その後、この新しい JSONObject に対して getString() のようなメソッドを呼び出すことができます。
  • person.getJSONArray("skills"): このメソッドは、キー "skills" に関連付けられた JSON 配列を取得します。
  • skills.length(): JSONArray 内の要素数を返します。
  • skills.getString(i): JSONArray 内の特定のインデックス i にある文字列要素を取得します。

パーサーのコンパイルと実行

この新しいクラスを実行して、出力を確認しましょう。

  1. WebIDE でターミナルを開きます。
  2. 以下のコマンドを実行します。
mvn compile exec:java -Dexec.mainClass="com.labex.ComplexJsonParser"

期待される出力は次のとおりです。

--- Parsing Complex JSON Data ---

Address:
  Street: 123 Main St
  City: Anytown

Skills:
  - Java
  - SQL
  - JavaScript

これにより、JSON 構造内のネストされたオブジェクトや配列をナビゲートしてデータを抽出する能力が実証されます。これは、複雑なデータフィードや API レスポンスを処理する上で重要なスキルです。

再利用可能な JSON ユーティリティの作成

ソフトウェア開発において、再利用可能なコードを書くことはベストプラクティスです。ファイル読み込みロジックを必要とする各クラスで繰り返すのではなく、ユーティリティクラスを作成できます。このアプローチは「Don't Repeat Yourself」(DRY)として知られており、コードをよりきれいに、保守しやすく、エラーを起こりにくくします。

JsonUtils クラスの作成

JSON ファイルの読み込みロジックをカプセル化するユーティリティクラスを作成しましょう。

  1. WebIDE で、src/main/java/com/labex ディレクトリ内に JsonUtils.java という名前の新しいファイルを作成します。
  2. 以下のコードを追加します。
package com.labex;

import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonUtils {

    /**
     * 相対パスから JSON ファイルを読み込み、JSONObject に解析します。
     *
     * @param filePath JSON ファイルへの相対パス。
     * @return ファイルの内容を表す JSONObject。
     * @throws IOException ファイルからの読み込み中に I/O エラーが発生した場合。
     */
    public static JSONObject readJsonObjectFromFile(String filePath) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filePath)));
        return new JSONObject(content);
    }
}

このクラスには、単一の static メソッド readJsonObjectFromFile が含まれています。static メソッドはインスタンスではなくクラス自体に属するため、オブジェクトを作成せずにクラス名(例:JsonUtils.readJsonObjectFromFile(...))を使用して直接呼び出すことができます。

ユーティリティクラスの使用

次に、新しいユーティリティを使用するメインアプリケーションクラスを作成しましょう。

  1. WebIDE で、src/main/java/com/labex ディレクトリ内に Main.java という名前の新しいファイルを作成します。
  2. Main.java に以下のコードを追加します。
package com.labex;

import org.json.JSONObject;

public class Main {
    public static void main(String[] args) {
        try {
            // ユーティリティクラスを使用して JSON ファイルを読み込みます
            JSONObject data = JsonUtils.readJsonObjectFromFile("src/main/resources/data.json");

            // 前と同様に JSONObject を操作できます
            String name = data.getString("name");
            String city = data.getJSONObject("address").getString("city");

            System.out.println("--- Data read using JsonUtils ---");
            System.out.println("Name: " + name);
            System.out.println("City: " + city);
            System.out.println("\nSuccessfully read JSON using JsonUtils.");

        } catch (Exception e) {
            System.out.println("An error occurred: " + e.getMessage());
        }
    }
}

この Main クラスははるかにきれいです。ファイル読み込みと解析のタスクを JsonUtils に委任し、結果の JSONObject で何をするかにのみ焦点を当てています。

メインアプリケーションの実行

最後に、Main クラスを実行しましょう。

  1. WebIDE でターミナルを開きます。
  2. 以下のコマンドを実行します。
mvn compile exec:java -Dexec.mainClass="com.labex.Main"

以下の出力が表示されます。

--- Data read using JsonUtils ---
Name: John Doe
City: Anytown

Successfully read JSON using JsonUtils.

ユーティリティクラスを作成することで、コードがよりモジュール化され、再利用可能になりました。これは効果的なソフトウェアエンジニアリングの重要な原則です。

まとめ

この実験では、Java で JSON ファイルを扱う実践的なスキルを習得しました。基本的なセットアップから高度な解析技術に進み、最終的には再利用可能なコードを作成しました。

学んだことの概要を以下に示します。

  • プロジェクトセットアップ: Maven プロジェクトの構造化方法と、JSON を扱うための外部ライブラリ(org.jsonなど)の組み込み方法を学びました。
  • JSON ファイルの作成: 文字列、数値、ブール値、ネストされたオブジェクト、配列など、さまざまなデータ型を含む、整形された JSON ファイルを作成しました。
  • 相対パスからの読み込み: アプリケーションのポータビリティを高める技術である、相対パスを使用したファイル読み込みを成功させました。
  • JSON の解析: org.jsonライブラリを使用して、JSON 文字列をJSONObjectおよびJSONArrayオブジェクトに解析し、プログラムでデータにアクセスできるようにしました。
  • 複雑な構造の処理: ネストされた JSON オブジェクトをナビゲートし、JSON 配列を反復処理して複雑なデータを抽出する方法を学びました。
  • コードの再利用性: ファイル読み込みロジックをカプセル化するJsonUtilsクラスを作成することで、DRY(Don't Repeat Yourself)の原則を適用し、よりクリーンで保守しやすいコードを実現しました。

JSON データの読み込み、解析、操作能力は、Web サービス、API 統合、またはアプリケーション構成に関わるあらゆる Java 開発者にとって不可欠です。この実験で構築した基礎は、より複雑な開発チャレンジに取り組む際に非常に役立つでしょう。