В какой-то момент каждый разработчик набирает достаточное количество навыков, и у него появляется мысль о создании собственного проекта, чтобы применить знания на практике. Легче всего взяться за веб-проект, так как реализация веб-приложения не скована какими-либо ограничениями, как, например, десктопные приложения. Клиенту нужен только браузер, и он может взаимодействовать с приложением не скачивая каких-либо дистрибутивов. Без регистрации и смс, как говорится (хотя это зависит от самого приложения). Так вот, для того, чтобы реализовать на Java хорошее веб-приложение, не обойтись без инструмента под названием Tomcat. Содержание:

Tomcat в курсе Javarush

Tomcat изучается на 9 уровне квеста Java Collections в курсе JavaRush. За 2 лекции Билаабо расскажет, как скачать и настроить Tomcat, а также собрать первое веб-приложение.

Tomcat — что это?

Tomcat — это контейнер сервлетов с открытым исходным кодом, который также выполняет функцию веб-сервера. При первом взгляде Tomcat кажется достаточно тяжелой темой, однако это не так. Большинство приложений Java запускаются с помощью командной строки и выполняют некоторые действия. Такие приложения реализуют одну заранее заданную функцию, после чего больше не выполняются. У таких программ, как правило, есть метод main, через который их можно запустить. Веб-приложение рассчитано на взаимодействие с клиентом. Если есть запрос от клиента, он обрабатывается, и пользователю отправляется ответ. Если нет, приложение простаивает. Как реализовать такую логику в стандартном приложении, учитывая, что нужно поддерживать сессии, принимать HTTP-запросы и прочее? Цикл while-true? Нет, здесь нужно надежное решение. Для этого и существует Tomcat. Фактически он представляет собой Java-приложение, которое заботится об открытии порта для взаимодействия с клиентом, настройке сессий, количестве запросов, длине заголовка и еще многих операциях.

Компоненты Tomcat

У Tomcat есть компоненты, выполняющие определенные функции, и о них стоит знать. Давай разберемся подробнее.

Catalina

Благодаря этому компоненту у разработчиков появляется возможность разворачивать свои программы в контейнере. Catalina реализует спецификацию Servlet API — основную веб-технологию в web-программировании на Java. Фактически Catalina — это контейнер сервлетов внутри Tomcat (подробнее рассмотрим это понятие ниже).

Jasper

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

Coyote

Это важный компонент, который прослушивает HTTP-запросы от клиента на определенном порту, предоставляет эти данные для обработки в приложении, а также возвращает пользователям ответы. То есть Coyote реализует функционал HTTP-сервера. Эти компоненты структурно можно описать следующей схемой: Здесь “на пальцах” показана примерная схема взаимодействия компонентов. Фактически схема работы Tomcat гораздо сложнее, однако для базового понимания этого достаточно.

Установка Tomcat

Чтобы использовать Tomcat в Java, его необходимо установить в систему. О том, как установить Tomcat можно прочитать в этой статье, где также рассматриваются и другие сервера приложений. Итак, имея работающий Tomcat, встроенный в IDEA, можно попробовать приготовить свой первый сервлет.

Как создать веб-приложение

Чтобы создать веб-приложение, следует придерживаться определенной структуры папок. У IntelliJ IDEA в меню создания проекта есть функция генерации веб-приложения. Создав проект таким образом, можно увидеть простую структуру: В src, как всегда — исходники, а в папке web сгенерированы web.xml и index.jsp. web.xml — это инструкция для Tomcat, где искать обработчики запросов и прочая информация. index.jsp — главная страница веб-приложения, куда пользователь должен попасть в первую очередь (речь идет о конфигурации по умолчанию). В качестве первого запуска можно просто отредактировать файл index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>
   <title>$Title$</title>
 </head>
 <body>
   <h1>Hello world!</h1>
 </body>
</html>
Если Tomcat установлен напрямую в IDEA, можно запустить сервер приложения: Клиент получает в браузер содержимое файла index.jsp, когда переходит на ‘/’, то есть на главную страницу. А теперь добавим ссылку на страницу, где будет располагаться текущее время сервера. Чтобы создать свой первый сервлет, нужно использовать библиотеку servlet-api.jar, который поставляется вместе с Tomcat (можно найти в папке lib). Создадим сервлет, который будет отображать на странице текущее время сервера. Для этого необходимо создать класс TimeWorker. Расположим его в папке src/ru/javarush/tomcat:
package ru.javarush.tomcat;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

public class TimeWorker extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     Date date = new Date();
     req.setAttribute("date", date.toString());
     req.getRequestDispatcher("time.jsp").forward(req, resp);
  }
}
TimeWorker наследуется от класса HttpServlet и переопределяет метод doGet. В этот метод мы получаем два параметра — request и response. В качестве примера в request сохраняется атрибут с названием data и содержащий строковое представление текущей даты. Затем вызывается requestDispatcher и в него передаются параметры request и response. Обработчик создан. Теперь нужно направить запросы именно на него. Пусть любой переход по /time будет вести на страницу time.jsp. Открываем web.xml, между тегами <web-app> вставляем следующую конфигурацию:
<servlet>
   <servlet-name>timeWorker</servlet-name>
   <servlet-class>ru.javarush.tomcat.TimeWorker</servlet-class>
   </servlet>

<servlet-mapping>
   <servlet-name>timeWorker</servlet-name>
   <url-pattern>/time</url-pattern>
</servlet-mapping>

<welcome-file-list>
   <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
Первый тег — servlet — определяет имя сервлета и указывает путь к классу-сервлету, который будет обрабатывать запросы. Второй тег — servlet-mapping — указывает, что сервлет с именем timeWorker будет вызываться тогда, когда поступит запрос на url /time. Третий тег — welcome-file-list — указывает файл, который будет вызван при переходе на url /. Это необходимо настраивать, если существует потребность изменить файл по-умолчанию. Здесь включен для примера. Теперь при переходе на /time будет вызываться метод doGet в классе TimeWorker и отдавать страницу time.jsp… которой нет. Создадим ее рядом с index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
   <title>Hello</title>
</head>
<body>
   <h1>Current server time: <%=request.getAttribute("date")%></h1>
</body>
</html>
Начало классическое, однако в теге h1 идет обращение к объекту request, которое обрамлено <%= и %>. Это теги шаблонизации. Код, заключенный в данные теги, вызывается до того, как будет отправлен клиенту. Ну а объекты request и response доступны в таких тегах в любом jsp-файле. В данном примере туда будет подставлено текущее время сервера, которое передает сервлет TimeWorker. В файл index.jsp для удобства создаем ссылку на /time:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
 <head>
   <title>$Title$</title>
 </head>
 <body>
   <h1>Hello world!</h1>
   <a href="/time">Узнать текущее время сервера</a>
 </body>
</html>
Запускаем пример: Переходим по ссылке: Отлично, все работает. В примере мы реализовали переход с главной страницы на вспомогательную, в которую был передан параметр и отображен для пользователя. При наличии проблем с запуском сервлетов рекомендую прочитать этот пост, где дают советы по решению этой проблемы. Для более полного ознакомления с сервлетами, рекомендуем прочитать статьи (часть 1, часть 2), где автор подробно расписывает создание простейшего приложения на сервлетах и jsp.

Как встроить приложение в работающий сервер

Несмотря на то, что встроенный Tomcat в IDEA — удобная фича, веб-приложение может быть перенесено на другой сервер и в другой контейнер. Рассмотрим вариант, когда необходимо встроить свое приложение в уже работающий сервер. Во-первых, необходимо дополнительно разобрать цель и функции контейнера сервлетов. Программа, которая приведена в примере выше — это веб-приложение. Класс TimeWorker — сервлет. Компоненты выполняют исключительно обработку запросов. Данные компоненты должны быть встроены в специальный контейнер сервлетов. Цель контейнера сервлетов — поддержка сервлетов и обеспечение их жизненного цикла. Простейший пример работы Tomcat — сканирование определенной папки с целью определить, появился ли в ней новый сервлет. Если да — инициализировать его и подготовить к приему запросов от клиентов. Если сервлет был обновлен, провести повторную инициализацию для обновления компонентов. При удалении сервлета — остановить обработку запросов, удалить сервлет из Tomcat.

Функции контейнера сервлетов

  1. Обмен данными между сервлетом и клиентами;
  2. Организация клиентских сессий;
  3. Создание программной среды для функционирования сервлета;
  4. Идентификация и авторизация клиентов;
  5. В большинстве случаев — управление метаданными (заголовки, методы и прочее).
Во-вторых, необходимо разобраться, как установить свой сервлет.

Установка сервлета

Tomcat принимает для обработки веб-приложения на Java, которые имеют расширение .war. Это как jar, только web. Файлы такого типа объединяют в себе JSP-файлы, сервлеты, class-файлы, статические ресурсы и прочее. При установке такого файла в Tomcat происходит его распаковка, а затем запуск, поэтому существует строгое требование к структуре файлов в проекте. Если проект был создан в IDEA, вся структура создана автоматически. Файл war можно создать стандартными средствами IDEA. Для этого необходимо зайти в ProjectStructure -> Artifacts -> Нажать “+” -> WebApplication: Archive. В открывшемся поле задать имя для итогового war-файла, например deployed_war. Ниже необходимо нажать на кнопку Create Manifest… Далее необходимо указать путь к папке web проекта. В ней будет создана папка META-INF, в которую будет помещен файл MANIFEST.MF. Далее следует нажать Apply и Ok. Чтобы собрать проект в war-файл, следует во вкладке Build выбрать опцию Build Artifact: В появившемся поле нужно нажать на deployed_war. Затем начнется сборка проекта и Intellij IDEA создаст папку out, в которой появится папка artifacts с именем нашего артефакта. В этой папке будет лежать файл deployed_war.war: Теперь можно деплоить этот файл в Tomcat. Деплой приложения проще всего выполнить из веб-интерфейса Tomcat. Просто нажмите кнопку выбора файла на вкладке Deploy, перейдите к местоположению файла WAR и выберите его, затем нажмите кнопку развертывания. В обоих случаях, если все пойдет хорошо, консоль Tomcat сообщит нам, что развертывание прошло успешно примерно таким выводом в консоль: INFO: Deployment of web application archive \path\to\deployed_war has finished in 4,833 ms

Польза Tomcat для разработки

Для разработчиков контейнеры сервлетов имеют огромную роль, так как решают целый спектр проблем. Для программирования на Java Tomcat обеспечивает несколько серьезных преимуществ:
  1. Самое главное, Tomcat может выполнять роль полноценного web-сервера. Благодаря этому развертывание приложений происходит гораздо быстрее, чем было раньше.Также Tomcat может выступать в роли классического контейнера сервлетов, который можно встроить в более крупный веб-сервер.

  2. Tomcat способствует обмену данными между клиентом и сервлетом, обеспечивает программный контекст для веб-приложений, берет на себя функции идентификации и авторизации клиентов, создание сессий для каждого из них.

  3. Предоставляет очень удобное управление JSP-страницами. Фактически веб-сервер может отдавать только html. Jasper, компонент Tomcat, компилирует код, содержащийся в шаблонных тегах JSP-страниц в корректный HTML-файл, который получает клиент. Вся логика шаблонизации находится внутри Tomcat, позволяя добавлять даже сложные конструкторы в классическую форму HTML.

И напоследок: очень часто начинающим разработчикам задают вопрос: возможно ли запустить Java-приложение без main-метода. На первый взгляд, если смотреть на примеры выше, можно. Наш сервлет был выполнен без метода main. Однако это не так. У Tomcat есть собственный метод main, который вызывается при запуске сервера. На такой вопрос можно попасться на собеседовании.

Дополнительные ссылки: