Java: Веб-технологии
Теория: Сервлеты
Javalin — это не единственный фреймворк на Java, вместе со Spring Boot их десятки. Несмотря на это многообразие, все они базируются на механизме сервлетов (servlets). В этом уроке мы обсудим, что это такое и почему об этом нужно знать.
Клей между фреймворками и веб-серверами
Любой веб-фреймворк работает не сам по себе. Для запуска написанного на нем приложения нужен веб-сервер. Такой веб-сервер загружает приложение внутрь себя и запускает. Из этого следует два вывода:
- Такой веб-сервер должен быть написан на том же языке — например, в Java среди основных веб-серверов выделяют Tomcat и Jetty
- Веб-сервер и фреймворк должны знать друг о друге, чтобы они могли работать совместно
Теперь представьте, что у нас есть десятки фреймворков и десятки веб-серверов. Как им всем знать друг о друге? В худшем случае нам пришлось бы писать код для совместимости каждого с каждым. Это было бы пустой тратой ресурсов команд разработчиков, а создание нового фреймворка было бы очень затруднено.
К счастью, эта проблема решилась еще в конце девяностых, когда появилась спецификация сервлетов. С тех пор все веб-сервера ориентируются только на сервлеты, а фреймворки, используют сервлеты для своей работы «под капотом». Все, что мы писали на Javalin, внутри фреймворка превращается в сервлеты:
Эта спецификация описывает способ написания универсального веб-приложения под Java, в котором код состоит из сервлетов.
Каждый сервлет – это класс, отвечающий за определенный маршрут. Во время работы веб-сервер принимает входящие запросы и передает их сервлетам, отвечающим за запрошенные адреса. Затем сервлеты возвращают ответы, которые отправляются клиентам.
Можно ли сделать вид, что для работы с фреймворками мы не обязаны ничего знать про сервлеты? С одной стороны, да, ведь сервлеты существуют только где-то внутри. На каком-то уровне их можно не замечать. С другой стороны, игнорировать сервлеты не стоит. Они встречаются везде: то в выводах в логах, то в настройках. Даже в Spring Boot настройки часто работают с механизмом сервлетов напрямую. Кроме того, о них могут спросить на собеседовании.
Первый сервлет
Рассмотрим создание полноценного приложения с помощью сервлетов на примере репозитория java-servlet-gradle. Начнем с класса сервлета:
Здесь мы видим переопределенный метод doGet(). Он вызывается на Get-запрос по адресу /about, указанному в аннотации. Внутри есть доступ к объектам запроса и ответа. В нашем примере данные запроса не используются, а вот в ответе отдается строчка текста. Перечислим моменты, на которые нужно обратить внимание:
- Jakarta (Jakarta EE) — это набор спецификаций и компонентов, предоставляющих решения для различных прикладных приложений. Туда входят и сервлеты и многое другое, что встречается в реальных проектах
- Сервлет наследуется от класса
HttpServlet, импортированного из Jakarta - Сервлет нужно пометить аннотацией
@WebServletс указанием имени и маршрута, за который этот сервлет отвечает
Так можно добавить любое количество сервлетов:
Чтобы запустить веб-сервер с нашим приложением, понадобится кое-что еще установить и настроить. Ниже урезанная версия файла build.gradle.kts:
После этого можно запустить приложение:
После этого приложение станет доступно в браузере по адресу http://localhost:8080. Если открыть страницу http://localhost:8080/about, то мы увидим текст Hello, Simple Servlet!.
Шаблонизатор Java Server Pages (JSP)
Кроме сервлетов, Jakarta содержит в себе JSP. Это простой шаблонизатор, который можно использовать для генерации HTML-страниц на сервере. Для примера создадим другой сервлет и посмотрим, как использовать JSP:
Общая структура сервлета не поменялась, но добавилось несколько деталей:
- Данные, которые мы хотим передать в шаблон, нужно записывать в объект запроса через метод
setAttribute() - Нужно явно указать, какой шаблон использовать
Для хранения шаблонов используется стандартная директория src/main/webapp/WEB-INF:
В шаблоне можно отметить четыре важных элемента:
- Первой строчкой идет
c:forEach— директива для работы JSP-тегов (они начинаются с префиксаc) - Запрос и ответ доступны в шаблоне напрямую через переменные
requestиresponse - Для вывода данных используется синтаксис
<%= %>, внутри которого можно вызывать Java-код - Для управляющих конструкций используется синтаксис на нестандартных тегах, которые превращаются в обычный HTML после обработки
Для работы JSP нужно добавить несколько зависимостей:



