Java: Веб-технологии
2026-02-26 20:19 Diff

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 нужно добавить несколько зависимостей: