Курсовая работа по дисциплине "Объектно-ориентированное программирование"
CLI-утилита, которая периодически опрашивает указанные REST API по HTTP и накапливает полученные ответы в один файл - JSON или CSV.
Написана на Java 21, сборка - Maven, сети/внешние API - модуль java.net.http. Для работы с JSON используется tools.jackson (Jackson 3), а CSV-вывод написан вручную. Тесты - JUnit 5 + Mockito.
Конфиг лежит в src/main/resources/apis.json - в нём описаны API, которые утилита умеет опрашивать. Для каждого API задаются: id, имя, базовый URL, нужен ли ключ и дополнительные пути (поля подробно описаны ниже).
Режим работы задаётся аргументами командной строки:
| Режим | Аргументы | Описание |
|---|---|---|
| Интерактивный | interactive |
Все параметры задаются в диалоге |
| Автоматический | automatic <csv|json> <maxConcurrent> <interval> |
Формат, лимит параллельных запросов и интервал задаются CLI аргументами, а остальное в диалоге |
maxConcurrent и interval должны быть неотрицательными целыми. interval = 0 означает непрерывный опрос.
В обоих режимах утилита работает одинаково:
- Определяет, какие API опрашивать.
- Для каждого выбранного API, если он требует дополнительного пути, дописывает этот путь к базовому URL.
- Запускает PollingManager: для каждого API планируется повторяющаяся задача опроса, которая шлёт
GETзапрос черезjava.net.http.HttpClient.- Каждый ответ оборачивается в структуру с полями:
id,source,timestamp,dataи дописывается в выходной файл. - Выполнение параллельных запросов ограничено
Semaphoreсогласно указанномуmaxConcurrentзначению, записи в файл синхронизированыReentrantLock. - Если интервал
t = 0, опрос идёт без пауз.
- Каждый ответ оборачивается в структуру с полями:
- Форматировщик (JSON или CSV) превращает ответ в запись и сохраняет результат в файл.
./mvnw exec:java -Dexec.args="interactive"Все параметры опроса задаются в диалоге. Утилита последовательно задаёт вопросы:
- Какие API опрашивать - по id (несколько через запятую, например
1,2,13) илиall. - Какие API выводить - по id (через запятую), фильтруется по уже выбранным. Или
all/none. - Режим записи -
0= перезаписать файл,1= дописывать. - Формат файла -
0= JSON,1= CSV. maxConcurrent- максимум одновременных запросов.interval- интервал опроса в секундах.- Для каждого API, которому нужен дополнительный путь - выбрать его (или
random, при котором параметр будет выбран 1 раз случайно).
После запуска опроса ввод stop (и enter) останавливает опрос, выходит в graceful завершение. Если за 20 секунд все запросы не получили ответ, менеджер прерывает их. Сохраняет результат.
./mvnw exec:java -Dexec.args="automatic json 3 10"Формат, лимит параллельных запросов и интервал передаются в CLI. У пользователя спрашивается только то, какие API опрашивать. Файл перезаписывается. Если требуется дополнительный путь для API, то он выбирается случайно.
Остановка - Ctrl+C, механизм завершения работы приложения тот же, что и в интерактивном режиме.
[
{
"id": 1,
"source": "The Movie Database",
"timestamp": "2026-01-01T12:00:00+00:00",
"data": { ...сам ответ API... }
}
]id инкрементируется автоматически.
Каждая новая запись добавляется строкой. Вложенные объекты превращаются в колонки с точечной нотацией (data.location.city), массивы объектов разворачиваются в несколько строк, примитивные массивы склеиваются символом |. Заголовки из разных API сливаются, у отсутствующих колонок пусто.
Каждый элемент массива:
id- числовой идентификатор (по нему выбираем API в CLI)name- отображаемое имяkey_needed- нужен ли ключ (тогда в заголовокAuthorizationдописываетсяAPI_KEY)API_KEY- сам ключ (в примере заглушкаkey)base_request_url- базовый URLadditional_path_needed- нужен ли доп. путь к базовому URLadditional_paths- доступные дополнительные путиheaders- заголовки
Шаблон здесь.
Сборка и прогон всех тестов:
./mvnw clean test # macOS / Linux
mvnw.cmd clean test # WindowsЗапуск из командной строки:
./mvnw exec:java -Dexec.args="interactive"
./mvnw exec:java -Dexec.args="automatic json 3 10"Тесты описаны в документации тестов.
Актуальный отчёт JaCoCo автоматически публикуется с помощью GitHub Pages при каждом прогоне CI на ветке main.