Skip to content

Repository files navigation

Weather Viewer

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

Описание

Проект разработан в рамках учебного курса Java Backend Learning Course. Приложение интегрировано с внешним сервисом OpenWeatherMap API для получения актуальных погодных данных. В проекте реализована ручная система авторизации на базе сессий и cookies (без использования Spring Security).

Live Demo

Проект развернут и доступен по адресу: Weather Viewer

Готовый тестовый аккаунт:

  • login: reviewer
  • password: qwerty123

Основной функционал

  • Интеграция с OpenWeather API: Поиск населенных пунктов по названию (Geocoding API) и получение детальной погодной сводки по координатам.
  • Персональные коллекции локаций: Добавление и удаление городов из персонального списка мониторинга для каждого авторизованного пользователя.
  • Ручная система аутентификации: Управление жизненным циклом сессий и безопасное хеширование паролей (BCrypt) с сохранением состояния через cookies.
  • Защита от дубликатов локаций: Отображение координат (Lat/Lon) для точной идентификации городов с одинаковыми названиями на уровне UI.
  • Глобальная обработка исключений: Единый GlobalExceptionHandler (@ControllerAdvice) для перехвата бизнес-ошибок (например, недоступность внешнего API) и корректной маршрутизации.
  • Контейнеризация и Деплой: Оптимизированная Multi-stage сборка Docker-образа и оркестрация базы данных, кэша и приложения через docker-compose.

Особенности реализации

В проекте старался соблюдать принципы Clean Architecture:

  • Изоляция DTO и Сущностей: Строгое разделение между Hibernate Entities и Data Transfer Objects (с использованием MapStruct) для предотвращения утечки бизнес-логики на слой представления.
  • Паттерн PRG (Post-Redirect-Get): Исключено дублирование действий пользователя (например, повторное добавление локации) при обновлении страницы.
  • Изоляция Context Path: Настроена корректная передача путей между Tomcat и Nginx без использования хардкода, что позволяет приложению прозрачно работать как локально, так и на VPS.
  • Слой UI (Thymeleaf & Bootstrap 5): Динамический рендеринг HTML на стороне сервера с использованием утилит форматирования чисел и условного отображения (conditional rendering).
  • Слой доступа к данным (Repository): Использование Spring Data JPA для инкапсуляции логики управления EntityManager при взаимодействии с PostgreSQL.
  • Кэширование статики на уровне Web-сервера: Nginx настроен на долгосрочное кэширование статических ресурсов (CSS, JS, изображения) для снижения нагрузки на сервер и ускорения загрузки UI.
  • Кэширование сетевых ответов через Redis: Внедрение in-memory кэша для кратковременного сохранения ответов от OpenWeather API с целью минимизации задержек и лимитирования внешних запросов.
  • Фоновые задачи (Scheduler): Настройка планировщика для автоматической очистки просроченных сессий, срабатывающего по умолчанию один раз в час.
  • Контроль доступа (Interceptor): Внедрение перехватчика HTTP-запросов для защиты внутренних эндпоинтов приложения и API-вызовов от неавторизованного доступа.
  • Комплексная валидация данных: Применение стандартных аннотаций JSR-380 (@Size, @NotBlank) в связке с кастомными валидаторами для проверки кросс-полевых условий (например, совпадения введенных паролей при регистрации).

Технологии

  • Java 17
  • Spring MVC
  • Thymeleaf
  • Hibernate (JPA) & Hibernate Validator
  • PostgreSQL 15
  • Redis
  • MapStruct & Jackson
  • SLF4J & Logback
  • Docker & Docker Compose
  • JUnit 5 & Mockito
  • TestContainers
  • WireMock
  • Lombok
  • Nginx & Apache Tomcat 10+ (среда деплоя)

Установка и локальный запуск

Проект упакован в контейнеры, что избавляет от необходимости локальной установки JRE, Tomcat или баз данных.

⚠️ Конфигурация (Переменные окружения)

Перед запуском создайте файл .env в корне проекта со следующими переменными:

  • OPENWEATHER_API_KEY — (Обязательно) Ваш персональный ключ доступа к OpenWeather API.
  • DB_USERNAME — (Обязательно) Логин для PostgreSQL (например, postgres).
  • DB_PASSWORD — (Обязательно) Пароль для PostgreSQL.
  • REDIS_PASSWORD — (Обязательно) Пароль для Redis.

Запуск через Docker Compose

  1. Клонируйте репозиторий:
git clone https://github.com/XanderGI/WeatherViewer.git
cd WeatherViewer
  1. Убедитесь, что файл .env заполнен корректно.
  2. Запустите сборку и старт контейнеров в фоновом режиме:
docker compose up --build -d
  1. Приложение будет доступно по адресу: http://localhost:8080/

Локальный запуск (через Gretty Plugin)

Самый простой способ запустить проект локально без установки Tomcat — использовать встроенный плагин Gretty, настроенный в build.gradle:

  1. Клонируйте репозиторий:
git clone https://github.com/XanderGI/WeatherViewer.git
cd WeatherViewer
  1. Убедитесь, что файл .env заполнен корректно.
  2. Запустите проект через Gradle:
./gradlew appRun
  1. Приложение будет доступно по адресу: http://localhost:8080/

Структура проекта

├───main
│   ├───java
│   │   └───io.github.XanderGI
│   │       ├───config               // Конфигурационные классы Spring (Web, App)
│   │       ├───controller           // HTTP маршрутизация (Spring MVC Controllers)
│   │       │   └───advice           // Глобальный обработчик ошибок
│   │       │   └───interceptor      // Обработчик неавторизированных запросов
│   │       ├───dto                  // Объекты передачи данных
│   │       ├───entity               // Hibernate JPA сущности (User, Location, Session)
│   │       ├───exception            // Классы ислкючений
│   │       ├───mapper               // MapStruct (Конвертация Entity <-> DTO)
│   │       ├───repository           // Слой доступа к данным (Spring Data JPA / Hibernate)
│   │       ├───scheduler            // Scheduler для очисти сессий
│   │       ├───security             // Менеджер для управления Cookies
│   │       ├───service              // Бизнес-логика и интеграция с внешним API
│   │       └───validation           // Валидация(Hibernate Validator) 
│   ├───resources
│   │   ├───db/migration             // SQL-скрипты миграций (Flyway)
│   │   ├───application.properties   // Файл конфигурации приложения
│   │   └───logback.xml              // Файл настройки логирования
│   ├───webapp                       // HTML шаблоны Thymeleaf, Статические файлы(CSS, Изображения)
├───test                   // Интеграционные тесты сервисов и Mocking HTTP-клиента, тесты для Controller layer
├───Dockerfile             // Multi-stage сборка приложения
└───docker-compose.yaml    // Оркестрация инфраструктуры (App, Postgres, Redis)

🎓 Что я изучил в ходе реализации проекта

  • Работа со Spring MVC: Конфигурация контекста (XML и Java Config), настройка DispatcherServlet, маршрутизация HTTP-запросов, биндинг параметров и применение AOP-подходов для централизованной обработки исключений
  • Интеграция REST API: Использование встроенных HTTP-клиентов для выполнения сетевых запросов к внешним сервисам и покрытие данного функционала тестами с использованием WireMock.
  • Работа с сессиями и cookies: Проектирование механизма сессий и работы с cookies с нуля (отказ от стандартного JSESSIONID и Spring Security), включая создание Interceptor для защиты маршрутов.
  • Многопоточность и фоновые задачи: Конфигурация ThreadPool для изолированной обработки фоновых задач и реализация планировщика (Scheduler) для очистки просроченных сессий.
  • Реализациия Repository слоя с помощью Spring Data JPA: получил базовое представление как работать со Spring Data JPA, в ходе его практического использования узнал о его преимуществах и недостатках.
  • Асинхронное сетевое взаимодействие: Проведение рефакторинга синхронных вызовов в асинхронные с применением пула потоков и CompletableFuture для повышения пропускной способности приложения.
  • Оптимизация производительности с Redis: Внедрение и конфигурация in-memory кэша для сохранения ранее запрошенных локаций (снижение нагрузки на API), с полным покрытием логики кэширования интеграционными тестами.
  • Комплексная валидация: Применение стандарта Hibernate Validator для базовых проверок полей и реализация собственных аннотаций для кросс-полевой валидации DTO.
  • Интеграционное тестирование с TestContainers: Создание абстрактного тестового класса для автоматического поднятия изолированного контекста с контейнерами PostgreSQL и Redis на этапе прогона тестов.
  • Продвинутая контейнеризация: Разработка оптимизированного Dockerfile с разбиением на этапы (multi-stage: резолв зависимостей и упаковка .war артефакта) и установкой лимитов потребления RAM (512MB)

About

Pet project #5 using Spring MVC. Technologies: Spring, PostgreSQL, Hibernate, Redis, Thymeleaf, Flyway, WireMock, SLF4J(Logback), Lombok, MapStruct, Mockito, AssertJ, TestContainers.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages