- о сети;
- об архитектуре ПО;
- о протоколах HTTP/HTTPS;
- об основах Maven;
- о сервлетах (пишем простое веб-приложение).
Содержание:
- Что такое контейнер сервлетов
- Как используют контейнеры сервлетов
- Установка и запуск Tomcat"
- Развертывание приложения в Tomcat
- Использование HTTPS протокола вместо HTTP
- Генерация сертификата
- Настраиваем сервер
- Динамическая генерация HTML-страниц
- Альтернативы Tomcat
Что такое контейнер сервлетов
Это программа, которая запускается на сервере и умеет взаимодействовать с созданными нами сервлетами. Иными словами, если мы хотим запустить наше веб-приложение на сервере, мы сначала разворачиваем контейнер сервлетов, а потом помещаем в него сервлеты. Схема работы проста: когда клиент обращается на сервер, контейнер обрабатывает его запрос, определяет, какой именно сервлет должен его обработать и передает его.Как используют контейнеры сервлетов
Кроме маршрутизации запросов, контейнер сервлетов выполняет и другие функции:- Динамически генерирует HTML-страницы с JSP-файлов.
- Зашифровывает/расшифровывает HTTPS-сообщения.
- Предоставляет разграниченный доступ для администрирования сервлетов.
Установка и запуск Tomcat
Для установки Tomcat просто распакуй скачанный архив в нужную директорию.
Учти, что для запуска и работы Tomcat нужна Java версии 8 или выше. Убедись, что переменная среды JAVA_HOME ссылается на актуальную версию jdk.
Далее необходимо сконфигурировать доступ пользователей к Tomcat. Это делается в файле tomcat-users.xml, который находится в папке conf.
В Tomcat заранее предусмотрены четыре роли:
- manager-gui — доступ к графическому интерфейсу и странице статусов;
- manager-script — доступ к текстовому интерфейсу и странице статусов;
- manager-jmx — доступ к JMX и странице статусов;
- manager-status — доступ только к странице статусов.
Внутри тега <tomcat-users> явно пропишем эти роли и назначим их нашему юзеру:
<role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user username="user" password="password" roles="manager-gui, manager-script, manager-jmx, manager-status"/>
Теперь все готово к запуску!
В папке bin запусти файл startup.bat (startup.sh на Linux).
Через несколько секунд в браузере открой ссылку http://localhost:8080/. Там появится графический менеджер:
Если видишь такое меню, значит, Tomcat запущен.
Если не работает, вручную проверь переменные среды JAVA_HOME и CATALINA_HOME:
- JAVA_HOME — должна ссылаться на актуальную версию джавы 8+;
- CATALINA_HOME — должна ссылаться на Tomcat или отсутствовать (не должна указывать на другую версию Tomcat).
Развертывание приложения в Tomcat
Запустить Tomcat у нас получилось, стало быть, пришло время развернуть в нем какой-то проект. Давай используем сервлеты из прошлой статьи. MainServlet:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/hello")
public class MainServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
HttpSession session = req.getSession();
Integer visitCounter = (Integer) session.getAttribute("visitCounter");
if (visitCounter == null) {
visitCounter = 1;
} else {
visitCounter++;
}
session.setAttribute("visitCounter", visitCounter);
String username = req.getParameter("username");
resp.setContentType("text/html");
PrintWriter printWriter = resp.getWriter();
if (username == null) {
printWriter.write("Hello, Anonymous" + "
");
} else {
printWriter.write("Hello, " + username + "
");
}
printWriter.write("Page was visited " + visitCounter + " times.");
printWriter.close();
}
}
IndexServlet:
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.sendRedirect(req.getContextPath() + "/hello");
}
}
Перед развертыванием наши сервлеты необходимо упаковать в war-архив.
Обычно для этого используется Мавен, но для создания war-архива нужен файл web.xml, в котором мапятся все сервлеты. Мы же писали сервлеты с использованием новой аннотации @WebServlet, поэтому web.xml у нас нет. Благо, IDEA может выполнить грязную работу за нас и поштучно завернуть наш проект в war-архив.
Для этого нужно открыть структуру проекта (Ctrl + Shift + Alt + S) -> Artifacts -> Выбрать нужный варник -> Поставить галочку возле поля “Include in project build” -> Нажать “ОК”.
Билдим проект с помощью комбинации Ctrl + F9. Теперь в директории target лежит наш war-архив
Файл можно переназвать как-то попроще — например, servlet.war — и перенести в более удобное место — в C:\my\.
Когда варник готов к использованию, помещаем его в контейнер. Это можно сделать двумя способами.
С помощью графического интерфейса
Для этого переходим по ссылке http://localhost:8080/manager/html. Tomcat должен запросить логин и пароль.
Если ты повторял все действия за мной, то логин — user, пароль — password.
После успешной авторизации ты увидишь Tomcat Web Application Manager. В разделе Applications уже содержатся 5 приложений — это служебные приложения Tomcat, необходимые для упрощения работы с ним. В будущем их можно будет удалить.
Ниже находится раздел Deploy. С его помощью можно выбрать war-архив для развертывания. Пропишем путь и контекст вручную:
Нажимаем “Deploy”, видим, что в разделе Applications появилось наше приложение:
С помощью графического интерфейса Tomcat мы его можем останавливать, перезапускать, устанавливать длину сессии и удалять. При развертывании мы указали контекст /demo, а значит, обращаться к нашему приложению нужно по ссылке http://localhost:8080/demo. Проверь, все должно работать.Через файловую систему
Чтобы задеплоить приложение таким способом, необходимо открыть директорию, в которой разархивирован Tomcat, перейти в webapps. Здесь находятся знакомые нам служебные приложения:
Все, что требуется от нас — переместить сюда наш servlet.war.
Ждем несколько секунд, видим, что появилась новая папка servlet, а это значит, что наше приложение развернуто. Переходим в знакомый нам Application Manager интерфейс — http://localhost:8080/manager/. Здесь мы видим, что наше приложение развернуто в контексте /servlet:
При развертывании таким способом, контекст автоматически присваивается по названию развернутого war-архива. Для смены контекста можно переназвать новосозданную папку с приложением, но перед этим нужно удалить варник: в ином случае Tomcat повторно развернет приложение с именем архива.
Как видишь, деплоить приложения в Tomcat намного проще, чем может показаться. Но и другими его функциями пользоваться несложно. Давай проверим.
Использование HTTPS протокола вместо HTTP
Если помнишь, разницу между HTTP и HTTPS мы рассматривали в отдельной статье. HTTPS — тот же протокол, что и HTTP, только с использованием шифрования данных, которые передаются. На стороне клиента шифрованием занимается браузер, а шифрование на стороне сервера должны обеспечить мы. Так как HTTP запросы принимает и маршрутизирует Tomcat, логично будет делегировать ему и шифрование. Для этого необходимо:- Сгенерировать самоподписанный сертификат;
- Сделать дополнительные настройки сервера.
Генерация сертификата
В JDK независимо от версии поставляется большое количество утилит, одна из которых — keytool. Это инструмент для генерации ключей шифрования и работы с ними. Чтобы его использовать, с помощью командной строки перейдем в директорию C:\Program Files\Java\jdk1.8.0_181\bin и выполним команду keytool -genkey -alias tomcat -keyalg RSA.- keytool — запускаем утилиту с параметрами;
- -genkey — указываем, что мы хотим сгенерировать новый ключ;
- -alias tomcat — создаем псевдоним ключа;
- -keyalg RSA — выбираем RSA как алгоритм генерации ключа.
Настраиваем сервер
Теперь, когда сертификат готов, нужно подкорректировать серверные настройки, а именно — SSL-коннектор. Это делается в файле server.xml, который находится в apache-tomcat-9.0.30/conf/. Находим там блоки типа:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
type="RSA" />
</SSLHostConfig>
</Connector>
и возле них помещаем свою конфигурацию:
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="C:\Users\user\.keystore" keystorePass="mypass"
clientAuth="false" sslProtocol="TLS"/>
Параметрам keystoreFile и keystorePass присваиваем актуальные для нас значения, сохраняем и перезапускаем Tomcat с помощью файлов shutdown.bat и startup.bat.
Теперь сервер готов обрабатывать https-запросы, вот только немного по измененному адресу — https://localhost:8443/demo/hello.
При переходе по ссылке у тебя появится предупреждение о сомнительности сертификата, что и неудивительно. Как описывалось немного ранее, для получения нормального сертификата нужно воспользоваться услугами одного из сервисов сертификации. Но пока мы достигли нашей цели: приложение работает по HTTPS-протоколу, а это главное!
Динамическая генерация HTML-страниц
Теперь продолжим обзор других фич контейнеров сервлетов — динамической генерации HTML-страниц. Представь себе идеальный мир, где вместо скучного статичного HTML-кода можно было бы писать JAVA-код, используя переменные, циклы, массивы и другие конструкции языка. Представил? Хорошая новость — что-то похожее существует, плохая — не в полной мере. Если ты не догадался, речь идет о технологии JSP (Java Server Pages). Если коротко, это технология, которая позволяет вставлять в HTML-страницу куски JAVA-кода. Правда, потом этот код все равно превращается в HTML перед отправкой клиенту, но он будет динамически сгенерирован с учетом различных факторов. Например, можно использовать условные конструкции, и в зависимости от какого-то условия отдавать различный контент. Пример JSP-страницы:
<%@ page language="java"" %>
<html>
<head>
<title>JSP</title>
</head>
<body>
<%
String firstName="name";
String secondName="surname";
if(firstName.equals("name")){
out.print("Hello :"+firstName+"<br>");
}
if(firstName.equals("name") && secondName.equals("surname"))
{
out.print("Hello, my dear friend! <br>");
}
else
{
out.print("I don’t know you. Go away! <br>");
}
%>
</body>
</html>
Дополнительно о JSP можно почитать здесь.
Вообще... мы не ради этого здесь собрались, а ради контейнеров сервлетов! Причем тут JSP?
Все просто: превращение JAVA-кода из JSP в HTML-код осуществляет именно контейнер сервлетов. Когда сервлет собирается вернуть в качестве ответа JSP-контент, контейнер обращает на это внимание, и перед отправкой такого контента клиенту сначала превращает его в понятную для браузера HTML-страницу.
Сегодня известно много аналогов технологии JSP — Thymeleaf, FreeMarket, Mustache и другие. Все они работаю по схожему принципу. Какой из них выбирать для работы — дело вкуса.
Это касается и выбора контейнера сервлетов. В примерах мы использовали Tomcat — самый распространенный контейнер, но в некоторых проектах используются и другие. С самыми популярными стоит кратко ознакомиться и посмотреть на их отличия от Tomcat.
Альтернативы Tomcat
GlassFish — контейнер с открытым исходным кодом, разработку которого поддерживает Oracle.
В отличие от Tomcat, это полноценный веб-сервер, который кроме сервлетов может оперировать и другими компонентами из фреймворка JavaEE. В то же время, он использует намного больше оперативной памяти. Более гибкий при тонкой настройке сервера, что усложняет его использование. Стоит использовать при разработке приложений на фреймворке JavaEE.
WildFly — ранее Jboss. Также имеет открытый исходный код. Разрабатывается компанией Red Hat. Название изменили, чтобы избежать путаницы с другим продуктом компании — JBoss Enterprise Application Platform.
WildFly, как и GlassFish, — полноценный веб-сервер. Кстати, под капотом WildFly использует Tomcat, как контейнер сервлетов. В отличии от GlassFish, WildFly более легковесный и простой в настройке.
Jetty — аналогично предыдущим имеет открытый исходный код. Развивается компанией Eclipse.
Как и Tomcat, является простым контейнером сервлетов, без поддержки всех компонентов фреймворка JavaEE. В то же время, он более легковесный, и его можно запустить даже на мобильном телефоне. Он быстро запускается и останавливается, хорошо масштабируется. В отличие от Tomcat, имеет меньшее комьюнити и базу знаний.
WebLogic — лицензированное программное обеспечение, требующие покупки перед использованием. Принадлежит компании Oracle.
По сравнению с Tomcat, его функционал немного шире. Может работать с протоколом ftp. Но он не настолько гибкий при разработке и тестировании приложений.
WebSphere ( WebSphere Application Server, если быть точным) — платное программное обеспечение. Разрабатывается компаниеей IBM. Аналогично WildFly и GlassFish является полноценным сервером приложений. Но у него более дружелюбный интерфейс настройки, плюс высокая надежность в работе.
Из минусов — он использует очень много ресурсов, долго запускается и останавливается, что не очень удобно при разработке небольших проектов.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
/usr/share/tomcat9/bin
создаём файликsetenv.sh
и прописываем туда путь к JDK, которую должен использовать Tomcat. Например, я установил версию 14 (58 по таблице): Перезапуск сервера - командойsudo systemctl restart tomcat9
(как и любую другую службу). 2) Ключи для HTTPS После генерации ключа (./bin/keytool) файл с ним (.keystore) лежит в домашней папке: -/home/user/.keystore
(если запускали под юзером) -/root/.keystore
(если запускали как root) Он скрытый, т.к. начинается на точку, поэтому проверьте, что видите скрытые файлы. Также убедитесь, что Tomcat имеет все права для работы с файлом ключа. Если он будет лежать в /root/ с правами только для root - HTTPS не заработает.