> For the complete documentation index, see [llms.txt](https://opu.gitbook.io/oop/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://opu.gitbook.io/oop/second-term/lectures/lecture-3-4.md).

# Лекция 3-4

## Тема: Клиент-серверная архитектура приложения. Сокеты в Java. Технология Java Servlets. Проект Spring Boot. Быстрое создание приложения с помощью Spring Boot. Архитектура Spring-приложения (web layer, service layer, repository layer).

## Клиент-серверная архитектура

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

Архитектура "клиент-сервер" определяет общие принципы организации взаимодействия, где имеются серверы (узлы-поставщики некоторых специфичных функций и сервисов) и клиенты, (потребители этих сервисов).

Между клиентами и серверами должны быть установлены правила взаимодействия, которые называются протоколом взаимодействия или протоколом обмена. Каждая часть взаимодействует друг с другом, обмениваясь сообщениями в заранее согласованном формате.

{% hint style="info" %}
Более подробно про клиент-серверное взаимодействие читайте здесь - <http://bit.ly/2qmKbHk>
{% endhint %}

В рамках данного курса рассматривается так называемая "трехзвенная архитектура"

![](/files/-LtYCdWC7V2S8XZsQ3q8)

Компоненты трехзвенной архитектуры:

* клиент - этот компонент отвечает за представление данных конечному пользователю;
* выделенный сервер приложений - здесь содержится бизнес-логика приложения;
* сервер БД - предоставляет запрашиваемые данные.

**Сервер приложений (application server)** – сервисная программа, которая обеспечивает доступ клиентов к прикладным программам, выполняющимся на сервере.

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

{% hint style="info" %}
Информация о сервере приложений - <http://bit.ly/2qt2Q4t>. \
Отличия веб-сервера и сервера приложений - <http://bit.ly/2qlUaNe>\
Подробнее про сервлеты и контейнеры сервлетов - <http://bit.ly/2Q9GAaP>
{% endhint %}

## Технология Java Servlets

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

Среди предложенных решений по созданию динамических страниц, одной из первых была технология **Java Servlets**. В то время это была революционная технология, которая позволяла расширить возможности веб-серверов на основе модели запрос-ответ (request - response). Технология сервлетов позволяла веб-серверам обрабатывать HTTP-запросы и динамически генерировать веб-странички в зависимости от HTTP-запроса.

{% hint style="info" %}
На данный момент актуальной версией технологии является версия 4.0, спецификацию технологии смотрите [здесь](https://jcp.org/en/jsr/detail?id=369).
{% endhint %}

Несмотря на почтенный возраст, технология сервлетов претерпела серьезные изменения для того, чтобы соответствовать современной технологии разработки веб-приложений. На данный момент, технология сервлетов является наиболее часто используемой технологией для обработки HTTP запросов/откликов. Кроме того, сервлеты являются базой для почти всех Java-фреймворков, которые работают с HTTP протоколом (JSF, Struts, Spring MVC, BIRT и так далее).

**Сервлет (Servlet)**, по сути, является классом Java, который используется для расширения возможностей сервером, предназначенных для размещения приложений. Сервлеты могут отвечать на запросы и генерировать отклики. Базовым классом для всех сервлетов является класс `javax.servlet.GenericServlet`. Этот класс определяет обобщенный, независимый от протокола сервлет.

Схема работы технологии сервлетов представлена на рисунке ниже

![Схема работы технологии Java Servlets](/files/-MVxREdkIBXJK22k7Oe6)

1. клиент (например, веб-браузер) передает HTTP-запрос веб-серверу. В случае, если от веб-сервера требуется предоставить статический файл или какой-то ресурс (например, изображение), то он просто возвращает требуемый статический файл или ресурс;
2. если веб-сервер не может самостоятельно обработать HTTP-запрос (например, пользователь передает какие-то данные либо требуется предоставить динамическую страницу и так далее), веб-сервер передает этот запрос web-контейнеру (его еще называют servlet-контейнером);
3. контейнер определяет – какой сервлет может выполнить этот запрос, создает объекты классов `HttpServletRequest` и `HttpServletResponse`, создает thread, создает объект класса сервлета и передает ему объекты классов `HttpServletRequest` и `HttpServletResponse`;
4. Контейнер вызывает метод сервлета `service()`, который вызывает соответствующий HTTP-запросу метод (например, если запрос был **HTTP** **GET**, то будет вызван метод `doGet()`, подробнее этот вопрос будет разбираться далее), которому, в качестве аргументов, передает объекты классов `HttpServletRequest` и `HttpServletResponse`;
5. Соответствующий метод (например, метод `doGet()`) возвращает динамическую страницу внутри объекта класса `HttpServletResponse`, ссылку на который имеет контейнер;
6. После этого поток завершается, контейнер конвертирует объект класса `HttpServletResponse` в HTTP-отклик (HTTP response) и отдает его веб-серверу, который возвращает его клиенту.

### Фреймворк Spring

**Spring** – свободно-распространяемый легковесный фреймворк, призванный упростить разработку корпоративных и веб-приложений (можно использовать и для любых других типов приложений) на языке Java (является альтернативной стеку Jakarta EE).

![](/files/-Lta_quWkLgtNog-OVL5)

В данный момент Spring представляет собой целый набор модулей, которые можно использовать выборочно для тех или иных проектов.

![](/files/-Lta_uvl51mwhOi_-HRH)

Дадим краткую характеристику **некоторым модулям** **Spring**:

* **Spring** **Core** – ядро платформы, предоставляет базовые средства для создания приложений — управление компонентами (бинами, beans), внедрение зависимостей, MVC фреймворк, транзакции, базовый доступ к БД. В основном это низкоуровневые компоненты и абстракции. По сути, неявно используется всеми другими компонентами;
* **Spring** **MVC** – обеспечивает архитектуру паттерна Model-View-Controller при помощи слабо связанных готовых компонентов для разработки веб-приложений;
* **Spring Data** – обеспечивает доступ к данным: реляционные и нереляционные БД, KV хранилища и т.п.;
* **Spring Cloud** – используется для микросервисной архитектуры;
* **Spring Security** – авторизация и аутентификация, доступ к данным, методам и т.п. OAuth, LDAP, и различные провайдеры.

### **Spring** **Boot**

Проект **Spring** **Boot** – решение, которое позволяет вам легко создавать полноценные приложения Spring, про которые можно сказать «просто запусти».

Spring Boot позволяет быстро создать и сконфигурировать (т.е. настроить зависимости между компонентами) приложение, упаковать его в исполняемый самодостаточный артефакт. Это то связующее звено, которое объединяет вместе набор компонентов в готовое приложение.

**Особенности** **Spring Boot:**

* создание полноценных Spring-приложений;
* встроенный сервлет-контейнер (Tomcat или Jetty);
* обеспечивает начальные pom-файлы для упрощения конфигурации Maven;
* используется автоконфигурация, где это возможно;
* используется принцип «**convention over configuration**». Для большинства конфигураций не нужно ничего настраивать.

Изучение фреймворка Spring лучше всего начать с установки требуемого программного обеспечения и разработки тестового приложения с помощью Spring Boot.

### Установка программного обеспечения

Для выполнения домашнего задания нам понадобится следующее программное обеспечение:

* JDK - <http://www.oracle.com/technetwork/java/javase/downloads/index.html>;
* приложение Postman - <https://www.getpostman.com/downloads/>;
* среда разработки, которая поддерживает Spring (например, IntelliJ IDEA Ultimate Edition или дистрибутив Eclipse под названием Spring Tool Suite –  <https://spring.io/tools>) либо любая другая IDE с поддержкой Java и Maven.

### Создание Spring Boot проекта

Существует несколько способов создать Spring Boot проект. Из наиболее простых способов можно выделить:

* генерация готового проекта на сайте <https://start.spring.io/> (проект **Spring Initializr**);
* создание проекта средствами IDE.

Создадим проект с помощью мастера Intellij IDEA. Создадим новый Spring Boot проект (выберите пункт Spring Initializr). Необходимо указать JDK, метаданные проекта, а также выбрать из списка модулей нужные нам модули Spring

![](/files/-Ltuv4_Cp3iDk0fX5tjA)

Для выполнения задания нам необходимо выбрать web-модуль. Панель выбранных компонентов будет иметь следующий вид:

![](/files/-LtuvjzsUc8TFdmOFjF8)

После окончания работы мастера создания проектов, мы получим стартовый проект Spring Boot. Рассмотрим структуру проекта и обозначим ключевые файлы:

![](/files/-Ltuw67XMok_w5URCw0W)

* **HotelApplication.java** - стартовый класс Spring Boot приложения;
* **application.properties** - файл с настройками приложения. В нем можно переопределить настройки по умолчанию;
* **pom.xml** - POM-файл проекта. Используется сборщиком Maven.

**POM-файл** (Project Object Model) – это XML-файл, который содержит информацию о деталях проекта, и конфигурации для создания проекта на Maven. Он всегда находится в базовом каталоге проекта. Во время выполнения задач, Maven ищет pom-файл в базовой директории проекта. Он читает его и получает необходимую информацию, после чего выполняет задачи.

Корневым элементом является элемент **\<project>**. Внутри тега project содержится основная и обязательная информация о проекте.

**Зависимости (dependency)** – это те библиотеки, которые непосредственно используются в проекте для компиляции кода или его тестирования.

Мы создаем RESTful веб-службу с помощью Spring Boot, поэтому нам нужно «подтянуть» для нашего проекта различные Spring-модули (библиотеки с классами, jar-файлы).

В обычных проектах нам бы было необходимо добавлять каждую зависимость вручную, но Spring Boot позаботился о нас и предоставил нам своего рода «мета-зависимости». Смысл их в том, что Spring Boot понимает, что если вы создаете web-приложение то вам нужен примерно одинаковый набор jar-файлов, поэтому чтобы не писать каждый jar-файл отдельно, мы указываем одну зависимость, а она уже «подтянет» за нас другие отдельные зависимости для создания веб-приложения.

### Запуск приложения

Теперь давайте сразу запустим приложение. Убедимся, что приложение запущено успешно

![](/files/-LtuyLsgdeSF_fZgF4sp)

перейдем в браузер и попробуем зайти на сайт.

![](/files/-LtuykItBpm7_SPdrYfV)

Как видите, Spring Boot приложение успешно запущено. Так как Spring Boot берет на себя большую часть рутинной работы по созданию и запуску приложения, давайте разберемся, что же происходит, когда мы запускаем приложение:

1. Устанавливается конфигурация приложения по умолчанию;
2. Запускается **контекст приложения** **Spring** **(Spring** **application** **context)** – это контейнер для кода, который работает на сервере (службы, контроллеры и т.д.). Все приложения Spring имеют этот контекст, который запускается при запуске приложения. Spring Boot создает этот контекст при запуске приложения;
3. Выполняется сканирование пути к классам (class path scan). Чтобы добавить код в Spring Boot, необходимо создать свои классы и аннотировать их определенным образом. Например, если вы хотите добавить контроллер, вы создаете класс и аннотируете его с помощью аннотации @Controller и так далее. То есть, вы как бы помечаете ваши классы, что это контроллер, это сервис, это еще что-то. Spring сканирует эти классы и, в зависимости от нашего маркера, он работает с этими классами по-разному. То есть Spring сканирует ваш код и ищет классы с этими аннотациями (помимо маркеров, обычно в аннотациях содержатся другие метаданные, которые дают уточняющую информацию для Spring);
4. Запускается Tomcat-сервер. Мы как раз зашли на сервер через URL и получили страницу с ошибкой, так как на сервере не был предусмотрен обработчик запроса с таким URL. Мы не скачивали Tomcat и не устанавливали его – все за нас сделал Spring Boot.

### Структура enterprise-приложения Spring

Простое приложение Spring имеет трехслойную структуру:

* **Web** **layer** – верхний слой приложения. Он отвечает за обработку ввода пользователя и возврат корректного ответа. Также веб-слой отвечает за обработку исключений, которые могут выбрасываться в других слоях приложения. Так как веб-слой является точкой входа в приложение, он также отвечает за аутентификацию и является первой линией защиты приложения;
* **Service** **layer** – слой сервисов, находится ниже веб-слоя. Этот слой содержит сервисы приложения и инфраструктуры. Сервисы приложения предоставляют публичный API сервисного слоя. Они также отвечают за транзакции и авторизацию. Инфраструктурные сервисы содержат код для взаимодействия с внешними ресурсами, такими как файловая система, базы данных, почтовые сервера и так далее. Часто эти сервисы используются несколькими сервисами приложения;
* **Repository** **layer** – самый нижний слой приложения. Он отвечает за взаимодействие с используемыми хранилищами данных.

![](/files/-LtuzU3rHAnsT1M8m9pd)

##
