Как читать JSON-файл по относительному пути в Java

JavaBeginner
Практиковаться сейчас

Введение

В современной разработке на Java работа с JSON (JavaScript Object Notation) является фундаментальным навыком. JSON — это де-факто стандарт для обмена данными в веб-приложениях и API благодаря своему удобочитаемому формату и простоте парсинга машинами.

Этот учебник представляет собой полное руководство по чтению и парсингу JSON-файлов из относительного пути в ваших Java-приложениях. Вы узнаете, как настроить проект Maven с необходимыми зависимостями, создать и структурировать JSON-файл, прочитать его из относительного пути и разобрать его содержимое, включая сложные вложенные данные.

К концу этой лабораторной работы вы будете уверенно управлять данными JSON в своих Java-проектах, что является критически важным навыком для любого разработчика, работающего с веб-сервисами, API или конфигурационными файлами.

Настройка проекта и создание JSON-файла

Прежде чем мы сможем прочитать JSON-файл, нам нужно настроить среду проекта и создать сам файл. В этой лабораторной работе для управления зависимостями проекта используется Apache Maven. Начальная настройка уже создала для вас стандартную структуру проекта Maven.

Понимание структуры проекта

В файловом проводнике WebIDE слева вы увидите следующую структуру внутри директории ~/project:

  • pom.xml: Файл Project Object Model (POM) для Maven. Он определяет зависимости проекта и конфигурации сборки.
  • src/main/java: Директория для вашего исходного кода на Java.
  • src/main/resources: Директория для ресурсных файлов, таких как файлы конфигурации или данных.

Файл pom.xml предварительно сконфигурирован для включения библиотеки org.json, популярного выбора для работы с JSON в Java.

Создание файла данных JSON

Теперь давайте создадим JSON-файл, который мы будем читать на последующих шагах.

  1. В файловом проводнике WebIDE перейдите в директорию src/main/resources.
  2. Щелкните правой кнопкой мыши по папке resources и выберите "New File" (Создать файл).
  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 и выберите "New File" (Создать файл).
  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;: Объявляет, что этот класс принадлежит пакету com.labex, в соответствии со стандартными соглашениями Java.
  • 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"): Этот метод извлекает вложенный JSON-объект, связанный с ключом "address". Затем вы можете вызывать методы, такие как getString(), для этого нового JSONObject.
  • person.getJSONArray("skills"): Этот метод извлекает JSON-массив, связанный с ключом "skills".
  • skills.length(): Возвращает количество элементов в JSONArray.
  • skills.getString(i): Извлекает строковый элемент по указанному индексу i в JSONArray.

Компиляция и запуск парсера

Давайте запустим этот новый класс, чтобы увидеть вывод.

  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 создайте новый файл с именем JsonUtils.java в директории src/main/java/com/labex.
  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 если при чтении файла возникает ошибка ввода-вывода.
     */
    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 создайте новый файл с именем Main.java в директории src/main/java/com/labex.
  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("--- Данные, прочитанные с помощью JsonUtils ---");
            System.out.println("Name: " + name);
            System.out.println("City: " + city);
            System.out.println("\nУспешно прочитан JSON с помощью JsonUtils.");

        } catch (Exception e) {
            System.out.println("Произошла ошибка: " + 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.

Создав класс утилиты, вы сделали свой код более модульным и повторно используемым, что является ключевым принципом эффективной разработки программного обеспечения.

Резюме

В этой лабораторной работе вы приобрели практические навыки работы с JSON-файлами в Java. Вы прошли путь от базовой настройки до продвинутых методов парсинга, завершив создание повторно используемого кода.

Вот краткий обзор того, что вы узнали:

  • Настройка проекта: Вы научились структурировать Maven-проект и включать внешние библиотеки, такие как org.json, для работы с JSON.
  • Создание JSON-файла: Вы создали корректно сформированный JSON-файл, содержащий различные типы данных, включая строки, числа, булевы значения, вложенные объекты и массивы.
  • Чтение по относительному пути: Вы успешно прочитали файл, используя относительный путь, что делает приложения более переносимыми.
  • Парсинг JSON: Вы использовали библиотеку org.json для парсинга JSON-строк в объекты JSONObject и JSONArray, что позволило вам программно получать доступ к данным.
  • Обработка сложных структур: Вы научились работать с вложенными JSON-объектами и перебирать JSON-массивы для извлечения сложных данных.
  • Повторное использование кода: Вы применили принцип DRY (Don't Repeat Yourself - Не повторяйся), создав класс JsonUtils для инкапсуляции логики чтения файлов, что привело к более чистому и поддерживаемому коду.

Способность читать, парсить и манипулировать данными JSON является неотъемлемой для любого Java-разработчика, занимающегося веб-сервисами, интеграцией API или конфигурацией приложений. Основа, которую вы заложили в этой лабораторной работе, будет бесценной при решении более сложных задач разработки.