Как прочитать JSON файл из относительного пути в Java

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

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

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

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

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

Понимание JSON и настройка вашего проекта

Что такое JSON?

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

  • Коллекция пар имя/значение (аналогично словарю или объекту)
  • Упорядоченный список значений (аналогично массиву или списку)

Вот простой пример JSON-объекта:

{
  "name": "John",
  "age": 30,
  "isStudent": false,
  "courses": ["Java", "Python", "JavaScript"]
}

Настройка проекта

Для этой лабораторной работы мы будем использовать библиотеку org.json, которая является широко используемой библиотекой для работы с JSON в Java. Библиотека уже добавлена в ваш проект через Maven.

Давайте проверим настройку проекта, открыв файл pom.xml:

  1. В WebIDE откройте панель проводника файлов в левой части.
  2. Перейдите в каталог ~/project.
  3. Откройте файл pom.xml, щелкнув по нему.

Вы должны увидеть следующую зависимость в файле pom.xml:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20230227</version>
</dependency>

Эта зависимость включает библиотеку org.json в наш проект, которая предоставляет такие классы, как JSONObject и JSONArray, которые мы будем использовать для работы с данными JSON.

Создание нашего первого Java-класса

Теперь давайте создадим простой Java-класс, чтобы протестировать нашу настройку:

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл JsonTester.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;

public class JsonTester {
    public static void main(String[] args) {
        // Create a simple JSON object
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", "Hello, JSON!");

        // Print the JSON object
        System.out.println("JSON Object: " + jsonObject.toString());
    }
}

Этот простой класс создает JSON-объект с одной парой ключ-значение и выводит его в консоль.

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

Теперь давайте скомпилируем и запустим нашу программу, чтобы убедиться, что все настроено правильно:

  1. Откройте терминал в WebIDE.
  2. Перейдите в каталог проекта:
cd ~/project
  1. Скомпилируйте Java-класс с помощью Maven:
mvn compile
  1. Запустите программу:
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) JsonTester

Вы должны увидеть вывод, похожий на этот:

JSON Object: {"message":"Hello, JSON!"}

Это подтверждает, что наш проект настроен правильно, и мы можем работать с JSON в Java.

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

На этом шаге мы создадим JSON-файл, который позже сможем прочитать из нашего Java-приложения. Мы поместим этот файл в каталог resources, который является распространенным местом для хранения файлов конфигурации и других ресурсов в Java-проектах.

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

Давайте создадим простой JSON-файл с некоторыми данными:

  1. В WebIDE перейдите в ~/project/src/main/resources.
  2. Щелкните правой кнопкой мыши по папке resources и выберите "New File" (Новый файл).
  3. Назовите файл data.json.
  4. Добавьте следующее JSON-содержимое в файл:
{
  "name": "John Doe",
  "age": 28,
  "email": "[email protected]",
  "isEmployed": true,
  "address": {
    "street": "123 Main St",
    "city": "Anytown",
    "zipCode": "12345"
  },
  "skills": ["Java", "SQL", "JavaScript", "HTML"]
}

Этот JSON-файл представляет человека с различными атрибутами, включая вложенные данные (объект address) и массив навыков.

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

Давайте разберем структуру этого JSON-файла:

  • Файл содержит один JSON-объект (заключенный в {}).
  • Объект имеет несколько свойств:
    • Простые свойства: name (строка), age (число), email (строка), isEmployed (boolean)
    • Вложенный объект: address, который имеет свои собственные свойства (street, city, zipCode)
    • Массив: skills, который содержит список строк

Понимание этой структуры будет важно, когда мы будем парсить данные JSON в нашем Java-приложении.

Проверка JSON-файла

Чтобы убедиться, что наш JSON-файл действителен, давайте создадим простую Java-программу для его проверки:

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл JsonValidator.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class JsonValidator {
    public static void main(String[] args) {
        try {
            // Get the absolute path to the resources directory
            String resourcesPath = new File("src/main/resources").getAbsolutePath();
            System.out.println("Resources directory: " + resourcesPath);

            // Path to the JSON file
            String jsonFilePath = resourcesPath + "/data.json";
            System.out.println("JSON file path: " + jsonFilePath);

            // Check if the file exists
            File jsonFile = new File(jsonFilePath);
            if (jsonFile.exists()) {
                System.out.println("JSON file exists.");

                // Read the contents of the file
                String jsonContent = new String(Files.readAllBytes(Paths.get(jsonFilePath)));

                // Parse the JSON to validate it
                JSONObject jsonObject = new JSONObject(jsonContent);
                System.out.println("JSON is valid.");
                System.out.println("Person's name: " + jsonObject.getString("name"));
            } else {
                System.out.println("JSON file does not exist at the specified path.");
            }
        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Эта программа выполняет несколько важных проверок:

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

Давайте запустим эту программу, чтобы проверить наш JSON-файл:

cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) JsonValidator

Вы должны увидеть вывод, похожий на этот:

Resources directory: /home/labex/project/src/main/resources
JSON file path: /home/labex/project/src/main/resources/data.json
JSON file exists.
JSON is valid.
Person's name: John Doe

Это подтверждает, что наш JSON-файл существует, действителен и может быть распарсен в Java.

Чтение JSON-файлов из относительных путей

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

Понимание относительных путей в Java

Относительный путь указывается относительно текущего рабочего каталога. В Java-приложениях текущим рабочим каталогом обычно является корневой каталог вашего проекта (в нашем случае, ~/project).

Например, если наш рабочий каталог — ~/project, то относительный путь к нашему JSON-файлу будет src/main/resources/data.json.

Создание класса чтения JSON

Давайте создадим Java-класс, который читает наш JSON-файл из относительного пути:

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл JsonReader.java.
  4. Добавьте следующий код в файл:
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 {
            // Specify the relative path to the JSON file
            String filePath = "src/main/resources/data.json";

            // Print the current working directory for reference
            System.out.println("Current working directory: " + System.getProperty("user.dir"));
            System.out.println("Trying to read JSON from: " + filePath);

            // Read the contents of the JSON file
            String jsonData = new String(Files.readAllBytes(Paths.get(filePath)));

            // Print the raw JSON data
            System.out.println("\nRaw JSON data:");
            System.out.println(jsonData);

            // Parse the JSON data into a JSONObject
            JSONObject jsonObject = new JSONObject(jsonData);

            // Access basic JSON data
            String name = jsonObject.getString("name");
            int age = jsonObject.getInt("age");
            String email = jsonObject.getString("email");
            boolean isEmployed = jsonObject.getBoolean("isEmployed");

            // Print the extracted data
            System.out.println("\nExtracted data:");
            System.out.println("Name: " + name);
            System.out.println("Age: " + age);
            System.out.println("Email: " + email);
            System.out.println("Employed: " + isEmployed);

            System.out.println("\nJSON file has been successfully read and parsed.");
        } catch (IOException e) {
            System.out.println("Error reading JSON file: " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println("Error parsing JSON: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Этот класс:

  1. Определяет относительный путь к нашему JSON-файлу
  2. Выводит текущий рабочий каталог для справки
  3. Читает содержимое файла с помощью Files.readAllBytes
  4. Парсит данные JSON в JSONObject
  5. Извлекает и выводит некоторые данные из JSON-объекта

Платформонезависимая обработка путей

Приведенный выше код использует прямые слеши (/) для пути к файлу, что работает как в системах на основе Unix (Linux, macOS), так и в Windows. Однако для более платформонезависимого подхода можно использовать константу File.separator:

String filePath = "src" + File.separator + "main" + File.separator + "resources" + File.separator + "data.json";

Это гарантирует использование правильного разделителя пути независимо от операционной системы.

Запуск JSON Reader

Давайте запустим нашу программу JSON Reader:

cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) JsonReader

Вы должны увидеть вывод, похожий на этот:

Current working directory: /home/labex/project
Trying to read JSON from: src/main/resources/data.json

Raw JSON data:
{
  "name": "John Doe",
  "age": 28,
  "email": "[email protected]",
  "isEmployed": true,
  "address": {
    "street": "123 Main St",
    "city": "Anytown",
    "zipCode": "12345"
  },
  "skills": ["Java", "SQL", "JavaScript", "HTML"]
}

Extracted data:
Name: John Doe
Age: 28
Email: [email protected]
Employed: true

JSON file has been successfully read and parsed.

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

Использование ресурсов класса для независимости от пути

Другой распространенный подход к чтению файлов в Java-приложениях — использование загрузчика классов для доступа к ресурсам в classpath. Этот подход особенно полезен для JAR-файлов и развернутых приложений.

Давайте создадим еще один класс, который демонстрирует этот подход:

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл ClasspathJsonReader.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

public class ClasspathJsonReader {
    public static void main(String[] args) {
        try {
            // Get the resource as an input stream
            InputStream inputStream = ClasspathJsonReader.class.getClassLoader().getResourceAsStream("data.json");

            if (inputStream == null) {
                System.out.println("Could not find data.json on the classpath");
                return;
            }

            // Read the input stream into a string
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder jsonData = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                jsonData.append(line).append("\n");
            }

            // Parse the JSON data
            JSONObject jsonObject = new JSONObject(jsonData.toString());

            // Print some data
            System.out.println("Name: " + jsonObject.getString("name"));
            System.out.println("Age: " + jsonObject.getInt("age"));

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

Этот метод будет работать независимо от рабочего каталога, если файл находится в classpath. Однако нам нужно сначала скомпилировать, чтобы сделать ресурсы доступными в classpath:

cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) ClasspathJsonReader

Вы можете не увидеть ожидаемый вывод, потому что ресурсы не копируются должным образом в classpath во время простой компиляции. Для производственного приложения вы будете использовать mvn package для создания JAR-файла со всеми включенными ресурсами.

Парсинг и обработка сложных JSON-структур

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

Наш файл data.json содержит вложенный объект (address) и массив (skills). На этом шаге мы создадим Java-программу, которая обращается к этим сложным структурам.

Создание парсера сложного JSON

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл ComplexJsonParser.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;
import org.json.JSONArray;
import java.nio.file.Files;
import java.nio.file.Paths;

public class ComplexJsonParser {
    public static void main(String[] args) {
        try {
            // Read the JSON file
            String filePath = "src/main/resources/data.json";
            String jsonData = new String(Files.readAllBytes(Paths.get(filePath)));

            // Parse the JSON data
            JSONObject person = new JSONObject(jsonData);

            // Print the person's basic information
            System.out.println("Person Information:");
            System.out.println("-------------------");
            System.out.println("Name: " + person.getString("name"));
            System.out.println("Age: " + person.getInt("age"));
            System.out.println("Email: " + person.getString("email"));
            System.out.println("Employed: " + person.getBoolean("isEmployed"));

            // Access the nested address object
            JSONObject address = person.getJSONObject("address");
            System.out.println("\nAddress Information:");
            System.out.println("-------------------");
            System.out.println("Street: " + address.getString("street"));
            System.out.println("City: " + address.getString("city"));
            System.out.println("Zip Code: " + address.getString("zipCode"));

            // Access the skills array
            JSONArray skills = person.getJSONArray("skills");
            System.out.println("\nSkills:");
            System.out.println("-------");
            for (int i = 0; i < skills.length(); i++) {
                System.out.println("- " + skills.getString(i));
            }

            // Demonstrating error handling: Trying to access a non-existent field
            try {
                String phoneNumber = person.getString("phoneNumber");
                System.out.println("Phone: " + phoneNumber);
            } catch (Exception e) {
                System.out.println("\nNote: The 'phoneNumber' field doesn't exist in the JSON data.");
            }

        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Эта программа:

  1. Читает и парсит данные JSON
  2. Получает доступ к основной информации о человеке
  3. Получает доступ к вложенному объекту address с помощью getJSONObject()
  4. Получает доступ к массиву skills с помощью getJSONArray() и перебирает его
  5. Демонстрирует обработку ошибок при попытке доступа к несуществующему полю

Запуск парсера сложного JSON

Давайте запустим нашу программу:

cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) ComplexJsonParser

Вы должны увидеть вывод, похожий на этот:

Person Information:
-------------------
Name: John Doe
Age: 28
Email: [email protected]
Employed: true

Address Information:
-------------------
Street: 123 Main St
City: Anytown
Zip Code: 12345

Skills:
-------
- Java
- SQL
- JavaScript
- HTML

Note: The 'phoneNumber' field doesn't exist in the JSON data.

Создание более сложного JSON-файла

Теперь давайте создадим более сложный JSON-файл для практики:

  1. В WebIDE перейдите в ~/project/src/main/resources.
  2. Щелкните правой кнопкой мыши по папке resources и выберите "New File" (Новый файл).
  3. Назовите файл company.json.
  4. Добавьте следующее JSON-содержимое в файл:
{
  "companyName": "Tech Innovators Inc.",
  "founded": 2005,
  "location": {
    "city": "San Francisco",
    "state": "CA",
    "country": "USA"
  },
  "isPublic": true,
  "employees": [
    {
      "id": 1,
      "name": "Alice Johnson",
      "position": "CEO",
      "department": "Executive",
      "skills": ["Leadership", "Strategy", "Public Speaking"]
    },
    {
      "id": 2,
      "name": "Bob Smith",
      "position": "CTO",
      "department": "Engineering",
      "skills": ["Java", "Architecture", "AI"]
    },
    {
      "id": 3,
      "name": "Carol Williams",
      "position": "Developer",
      "department": "Engineering",
      "skills": ["Java", "Python", "JavaScript"]
    }
  ],
  "departments": ["Executive", "Engineering", "Marketing", "Sales"],
  "annualRevenue": {
    "2020": 1500000,
    "2021": 1800000,
    "2022": 2200000
  }
}

Этот JSON-файл представляет компанию с вложенными объектами, массивами и массивами объектов.

Создание парсера для сложного JSON компании

Давайте создадим программу для парсинга этого более сложного JSON:

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл CompanyJsonParser.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;
import org.json.JSONArray;
import java.nio.file.Files;
import java.nio.file.Paths;

public class CompanyJsonParser {
    public static void main(String[] args) {
        try {
            // Read the JSON file
            String filePath = "src/main/resources/company.json";
            String jsonData = new String(Files.readAllBytes(Paths.get(filePath)));

            // Parse the JSON data
            JSONObject company = new JSONObject(jsonData);

            // Print the company's basic information
            System.out.println("Company Information:");
            System.out.println("--------------------");
            System.out.println("Name: " + company.getString("companyName"));
            System.out.println("Founded: " + company.getInt("founded"));
            System.out.println("Public: " + company.getBoolean("isPublic"));

            // Access the nested location object
            JSONObject location = company.getJSONObject("location");
            System.out.println("\nLocation:");
            System.out.println("--------");
            System.out.println("City: " + location.getString("city"));
            System.out.println("State: " + location.getString("state"));
            System.out.println("Country: " + location.getString("country"));

            // Access the departments array
            JSONArray departments = company.getJSONArray("departments");
            System.out.println("\nDepartments:");
            System.out.println("------------");
            for (int i = 0; i < departments.length(); i++) {
                System.out.println("- " + departments.getString(i));
            }

            // Access the employees array of objects
            JSONArray employees = company.getJSONArray("employees");
            System.out.println("\nEmployees:");
            System.out.println("---------");
            for (int i = 0; i < employees.length(); i++) {
                JSONObject employee = employees.getJSONObject(i);
                System.out.println("\nEmployee #" + employee.getInt("id"));
                System.out.println("Name: " + employee.getString("name"));
                System.out.println("Position: " + employee.getString("position"));
                System.out.println("Department: " + employee.getString("department"));

                // Access the skills array for each employee
                JSONArray skills = employee.getJSONArray("skills");
                System.out.println("Skills:");
                for (int j = 0; j < skills.length(); j++) {
                    System.out.println("  - " + skills.getString(j));
                }
            }

            // Access the annual revenue object
            JSONObject revenue = company.getJSONObject("annualRevenue");
            System.out.println("\nAnnual Revenue:");
            System.out.println("--------------");
            for (String year : revenue.keySet()) {
                System.out.println(year + ": $" + revenue.getInt(year));
            }

        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Эта программа:

  1. Читает и парсит сложные данные JSON компании
  2. Получает доступ к основной информации о компании
  3. Получает доступ к вложенному объекту location
  4. Перебирает массив departments
  5. Перебирает массив employees, который содержит объекты
  6. Для каждого сотрудника получает доступ к его основной информации и перебирает массив skills
  7. Перебирает данные о годовой выручке по годам

Запуск парсера JSON компании

Давайте запустим нашу программу:

cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) CompanyJsonParser

Вы должны увидеть подробный вывод, показывающий всю информацию, полученную из сложной структуры JSON компании.

Создание повторно используемого класса утилит JSON

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

Создание класса утилит JSON

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл JsonUtils.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;
import org.json.JSONArray;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * Utility class for handling JSON operations.
 */
public class JsonUtils {

    /**
     * Reads a JSON file from a relative path and returns it as a JSONObject.
     *
     * @param filePath The relative path to the JSON file
     * @return The JSONObject representing the file contents
     * @throws IOException If there's an error reading the file
     */
    public static JSONObject readJsonObjectFromFile(String filePath) throws IOException {
        String jsonData = new String(Files.readAllBytes(Paths.get(filePath)));
        return new JSONObject(jsonData);
    }

    /**
     * Reads a JSON file from a relative path and returns it as a JSONArray.
     *
     * @param filePath The relative path to the JSON file
     * @return The JSONArray representing the file contents
     * @throws IOException If there's an error reading the file
     */
    public static JSONArray readJsonArrayFromFile(String filePath) throws IOException {
        String jsonData = new String(Files.readAllBytes(Paths.get(filePath)));
        return new JSONArray(jsonData);
    }

    /**
     * Gets a string value from a JSONObject, or returns a default value if the key doesn't exist.
     *
     * @param jsonObject The JSONObject to extract from
     * @param key The key to look for
     * @param defaultValue The default value to return if the key doesn't exist
     * @return The string value or the default value
     */
    public static String getString(JSONObject jsonObject, String key, String defaultValue) {
        return jsonObject.has(key) ? jsonObject.getString(key) : defaultValue;
    }

    /**
     * Gets an integer value from a JSONObject, or returns a default value if the key doesn't exist.
     *
     * @param jsonObject The JSONObject to extract from
     * @param key The key to look for
     * @param defaultValue The default value to return if the key doesn't exist
     * @return The integer value or the default value
     */
    public static int getInt(JSONObject jsonObject, String key, int defaultValue) {
        return jsonObject.has(key) ? jsonObject.getInt(key) : defaultValue;
    }

    /**
     * Gets a boolean value from a JSONObject, or returns a default value if the key doesn't exist.
     *
     * @param jsonObject The JSONObject to extract from
     * @param key The key to look for
     * @param defaultValue The default value to return if the key doesn't exist
     * @return The boolean value or the default value
     */
    public static boolean getBoolean(JSONObject jsonObject, String key, boolean defaultValue) {
        return jsonObject.has(key) ? jsonObject.getBoolean(key) : defaultValue;
    }

    /**
     * Extracts a list of strings from a JSONArray.
     *
     * @param jsonArray The JSONArray to extract from
     * @return A List of strings
     */
    public static List<String> getStringList(JSONArray jsonArray) {
        List<String> result = new ArrayList<>();
        for (int i = 0; i < jsonArray.length(); i++) {
            result.add(jsonArray.getString(i));
        }
        return result;
    }

    /**
     * Pretty-prints a JSONObject.
     *
     * @param jsonObject The JSONObject to print
     * @return A formatted string representation of the JSONObject
     */
    public static String prettyPrint(JSONObject jsonObject) {
        return jsonObject.toString(4);  // Indent with 4 spaces
    }

    /**
     * Pretty-prints a JSONArray.
     *
     * @param jsonArray The JSONArray to print
     * @return A formatted string representation of the JSONArray
     */
    public static String prettyPrint(JSONArray jsonArray) {
        return jsonArray.toString(4);  // Indent with 4 spaces
    }
}

Этот класс утилит предоставляет несколько методов:

  • readJsonObjectFromFile: Читает JSON-файл и возвращает его как JSONObject
  • readJsonArrayFromFile: Читает JSON-файл и возвращает его как JSONArray
  • Несколько методов получения (getter) со значениями по умолчанию для безопасного извлечения данных из JSONObject
  • Метод для преобразования JSONArray строк в List<String>
  • Методы красивой печати (pretty-printing) для JSONObject и JSONArray

Создание тестового класса для нашей утилиты JSON

Теперь давайте создадим класс для тестирования нашей утилиты JSON:

  1. В WebIDE перейдите в ~/project/src/main/java.
  2. Щелкните правой кнопкой мыши по папке java и выберите "New File" (Новый файл).
  3. Назовите файл JsonUtilsDemo.java.
  4. Добавьте следующий код в файл:
import org.json.JSONObject;
import org.json.JSONArray;
import java.util.List;

public class JsonUtilsDemo {
    public static void main(String[] args) {
        try {
            // Read the person JSON file using our utility
            System.out.println("Reading person data...");
            JSONObject person = JsonUtils.readJsonObjectFromFile("src/main/resources/data.json");

            // Using our utility methods to safely extract data
            String name = JsonUtils.getString(person, "name", "Unknown");
            int age = JsonUtils.getInt(person, "age", 0);
            String email = JsonUtils.getString(person, "email", "No email");
            boolean isEmployed = JsonUtils.getBoolean(person, "isEmployed", false);

            // Using a default value for a non-existent field
            String phone = JsonUtils.getString(person, "phoneNumber", "No phone number");

            System.out.println("Person Information:");
            System.out.println("Name: " + name);
            System.out.println("Age: " + age);
            System.out.println("Email: " + email);
            System.out.println("Employed: " + isEmployed);
            System.out.println("Phone: " + phone);  // Will show the default value

            // Access the skills array and convert it to a List
            JSONArray skillsArray = person.getJSONArray("skills");
            List<String> skills = JsonUtils.getStringList(skillsArray);

            System.out.println("\nSkills:");
            for (String skill : skills) {
                System.out.println("- " + skill);
            }

            // Read the company JSON file
            System.out.println("\nReading company data...");
            JSONObject company = JsonUtils.readJsonObjectFromFile("src/main/resources/company.json");

            // Pretty-print the company data
            System.out.println("\nCompany Data (Pretty-Printed):");
            System.out.println(JsonUtils.prettyPrint(company));

            // Extract and display the employees
            JSONArray employees = company.getJSONArray("employees");
            System.out.println("\nEmployees (Pretty-Printed):");
            System.out.println(JsonUtils.prettyPrint(employees));

        } catch (Exception e) {
            System.out.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Эта программа:

  1. Использует наш класс JsonUtils для чтения JSON-файлов person и company
  2. Использует безопасные методы получения (getter) для извлечения данных со значениями по умолчанию
  3. Преобразует массив JSON в Java List
  4. Использует методы красивой печати (pretty-print) для отображения отформатированных данных JSON

Запуск демонстрации утилит JSON

Давайте запустим нашу демонстрационную программу:

cd ~/project
mvn compile
java -cp target/classes:$(mvn dependency:build-classpath -q -Dmdep.outputFile=/dev/stdout) JsonUtilsDemo

Вы должны увидеть вывод, демонстрирующий все функции нашего класса утилит JSON, включая красиво отформатированные данные JSON.

Преимущества повторно используемого класса утилит

Создание повторно используемого класса утилит для операций JSON предлагает несколько преимуществ:

  1. Повторное использование кода: Вам не нужно повторять один и тот же код парсинга JSON в нескольких местах.
  2. Обработка ошибок: Вы можете реализовать последовательную обработку ошибок в одном месте.
  3. Значения по умолчанию: Вы можете предоставить значения по умолчанию для отсутствующих полей JSON, что делает ваш код более надежным.
  4. Инкапсуляция: Детали парсинга JSON инкапсулированы в классе утилит.
  5. Удобство обслуживания: Если библиотека JSON изменится или вы захотите перейти на другую, вам нужно будет обновить только класс утилит.

В реальном приложении вы можете расширить этот класс утилит дополнительной функциональностью, такой как:

  • Запись данных JSON в файлы
  • Преобразование между объектами JSON и Java (сериализация/десериализация)
  • Проверка JSON по схеме
  • Обработка более сложных типов данных

Краткое описание того, что мы узнали

На протяжении этой лабораторной работы мы узнали:

  1. Основы JSON и то, как он используется в Java
  2. Как настроить Java-проект с зависимостями JSON
  3. Как создавать и проверять JSON-файлы
  4. Как читать JSON-файлы из относительных путей
  5. Как парсить и обрабатывать сложные JSON-структуры
  6. Как создать повторно используемый класс утилит для операций JSON

Эти навыки будут полезны во многих сценариях разработки на Java, от работы с RESTful API до обработки файлов конфигурации и хранения данных.

Резюме

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

  1. Вы настроили Java-проект с необходимыми зависимостями JSON и создали свой первый простой объект JSON.

  2. Вы создали JSON-файлы различной сложности и проверили их валидность.

  3. Вы узнали, как читать JSON-файлы из относительных путей, используя как стандартные файловые операции, так и подход с использованием classpath.

  4. Вы изучили, как парсить и обрабатывать сложные JSON-структуры, включая вложенные объекты и массивы.

  5. Вы создали повторно используемый класс утилит JSON, который инкапсулирует общие операции JSON и делает ваш код более удобным в обслуживании.

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

Продолжая свой путь разработки на Java, вы можете опираться на эти навыки для реализации более продвинутых функций, таких как:

  • Преобразование между объектами JSON и Java с использованием таких библиотек, как Jackson или Gson
  • Работа с RESTful API, которые обмениваются данными JSON
  • Реализация JSON Web Tokens (JWT) для аутентификации
  • Создание систем конфигурации на основе JSON

Знания, полученные в этой лабораторной работе, обеспечивают прочную основу для этих продвинутых тем.