JavaRush /Java блог /Random UA /Частина 6. Контейнери сервлетів
Professor Hans Noodles
41 рівень

Частина 6. Контейнери сервлетів

Стаття з групи Random UA
Цей матеріал - частина циклу "Введення в Enterprise-розробку". Попередні статті: Частина 6. Контейнери сервлетів - 1Минулої статті ми познайомабося із сервлетами, навчабося з їх допомогою створювати веб-додатки. Настав час уважніше поглянути на те, без чого це свято було б неможливим — контейнери сервлетів.

Зміст:

Що таке контейнер сервлетів

Це програма, яка запускається на сервері та вміє взаємодіяти зі створеними нами сервлетами. Іншими словами, якщо ми хочемо запустити наш веб-додаток на сервері, ми спочатку розгортаємо контейнер сервлетів, а потім поміщаємо до нього сервлети. Схема роботи проста: коли клієнт звертається на сервер, контейнер обробляє його запит, визначає який саме сервлет повинен його обробити і передає його. Частина 6. Контейнери сервлетів - 2

Як використовують контейнери сервлетів

Крім маршрутизації запитів, контейнер сервлетів виконує інші функції:
  1. Динамічно генерує HTML-сторінки із JSP-файлів.
  2. Зашифровує/розшифровує повідомлення HTTPS.
  3. Надає розмежований доступ для адміністрування сервлетів.
Загалом, звучить непогано, лишилося тільки розібратися, як це все застосувати. Ну а щоб навчитися щось використати, потрібно просто... спробувати це використати :) Тож сьогодні практикуватимемося! Найпопулярніший контейнер сервлетів - Apache Tomcat . Він має відкритий вихідний код і його можна використовувати безкоштовно. Скачай Tomcat для своєї операційної системи за цим посиланням і подивимося на роботу з контейнерами "у справі".

Встановлення та запуск Tomcat

  1. Для встановлення Tomcat просто розпакуй завантажений архів у потрібну директорію.

  2. Зверни увагу, що для запуску та роботи Tomcat потрібна Java версії 8 або вище. Переконайтеся, що змінне середовище JAVA_HOME посилається на актуальну версію jdk.

  3. Далі необхідно налаштувати доступ користувачів до 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"/>

    Тепер все готове до запуску!

  4. У папці bin запусти файл startup.bat (startup.sh на Linux).

  5. Через кілька секунд у браузері відкрий посилання http://localhost:8080/ . Там з'явиться графічний менеджер:

    Частина 6. Контейнери сервлетів – 3

    Якщо бачиш таке меню, то Tomcat запущений.

  6. Якщо не працює, вручну перевір змінні середовища 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" -> Натиснути "ОК". Частина 6. Контейнери сервлетів - 4Білдим проект за допомогою комбінації Ctrl+F9. Тепер у директорії target лежить наш war-архів Частина 6. Контейнери сервлетів - 5Файл можна переназвати якось простіше — наприклад, servlet.war — і перенести у зручніше місце — C:\my\. Коли варник готовий до використання,поміщаємо його в контейнер . Це можна зробити двома способами.
  1. За допомогою графічного інтерфейсу

    Для цього переходимо за посиланням http://localhost:8080/manager/html . Tomcat повинен запитити логін та пароль.

    Якщо ти повторював усі дії за мною, то логін – user, пароль – password .

    Після успішної авторизації побачиш Tomcat Web Application Manager. У розділі Applications вже містяться 5 додатків – це службові програми Tomcat, необхідні для спрощення роботи з ним. У майбутньому їх можна буде видалити.

    Частина 6. Контейнери сервлетів - 6

    Нижче наведено розділ Deploy. З його допомогою можна вибрати war-архів для розгортання. Пропишемо шлях та контекст вручну:

    Частина 6. Контейнери сервлетів - 7

    Натискаємо “Deploy”, бачимо, що у розділі Applications з'явився наш додаток:

    Частина 6. Контейнери сервлетів - 8 За допомогою графічного інтерфейсу Tomcat ми можемо його зупиняти, перезапускати, встановлювати довжину сесії і видаляти. При розгортанні ми вказали контекст /demo, а значить, звертатися до нашого додатку потрібно за посиланням http://localhost:8080/demo . Перевір, все має працювати.

  2. Через файлову систему

    Щоб задеплоїти програму таким способом, необхідно відкрити директорію, в якій розархівований Tomcat, перейти до webapps. Тут знаходяться знайомі нам службові програми:

    Частина 6. Контейнери сервлетів - 9

    Все, що потрібно від нас – перемістити сюди наші servlet.war.

    Чекаємо кілька секунд, бачимо, що з'явилася нова папка servlet, а це означає, що наша програма розгорнута. Переходимо в знайомий нам Application Manager інтерфейс - http://localhost:8080/manager/ . Тут ми бачимо, що наша програма розгорнута в контексті /servlet:

    Частина 6. Контейнери сервлетів – 10

    При розгортанні таким способом контекст автоматично присвоюється за назвою розгорнутого war-архіву. Для зміни контексту можна переназвати новостворену папку з програмою, але перед цим потрібно видалити варник: в іншому випадку Tomcat повторно розгорне програму з ім'ям архіву.

    Як бачиш, деплоїти програми в Tomcat набагато простіше, ніж може здатися. Але й іншими його функціями скористатися нескладно. Давай перевіримо.

Використання протоколу HTTPS замість HTTP

Якщо пам'ятаєш, різницю між HTTP та HTTPS ми розглядали в окремій статті . HTTPS — той самий протокол, що й HTTP, лише за допомогою шифрування даних, що передаються. На стороні клієнта шифрування займається браузер, а шифрування на стороні сервера повинні забезпечити ми. Так як HTTP запити приймає та маршрутизує Tomcat, логічно делегуватиме йому і шифрування. Для цього необхідно:
  1. Згенерувати самопідписаний сертифікат;
  2. Зробити додаткові параметри сервера.
Давай попрактикуємось у цьому.

Генерація сертифіката

У JDK незалежно від версії поставляється велика кількість утиліт, одна з яких – keytool . Це інструмент для створення ключів шифрування і роботи з ними. Щоб його використовувати, за допомогою командного рядка перейдемо в директорію C: Program Files Java jdk1.8.0_181bin і виконаємо команду keytool -genkey -alias tomcat -keyalg RSA .
  • keytool - запускаємо утиліту з параметрами;
  • -genkey - Вказуємо, що ми хочемо згенерувати новий ключ;
  • -alias tomcat - створюємо псевдонім ключа;
  • -keyalg RSA – вибираємо RSA як алгоритм генерації ключа.
Після виконання команди, утиліта розпочне з нами діалог: Частина 6. Контейнери сервлетів - 11Вводимо необхідну інформацію. Тепер ми створабо сховище ключів у нашому домашньому каталозі (для Windows це C:\Users\{username}\.keystore) та ключ tomcat у ньому. Ми згенерували простий сертифікат, на який лаятиметься більшість браузерів. Такий сертифікат не підійде для комерційних програм: його можна використовувати тільки в тестових цілях. На продакшн-сервері необхідно використовувати сертифікат від центру сертифікації (наприклад, https://letsencrypt.org/ ).

Налаштовуємо сервер

Тепер, коли сертифікат готовий, потрібно підкоригувати серверні налаштування, а саме 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

  1. GlassFish — контейнер із відкритим вихідним кодом, розробку якого підтримує Oracle.

    На відміну від Tomcat, це повноцінний веб-сервер, який, крім сервлетів, може оперувати й іншими компонентами з фреймворку JavaEE. У той же час він використовує набагато більше оперативної пам'яті. Гнучкіший при тонкому налаштуванні сервера, що ускладнює його використання. Варто використовувати при розробці програм на фреймворку JavaEE.

  2. WildFly - раніше Jboss . Також має відкритий вихідний код. Розробляється компанією Red Hat. Назва змінабо, щоб уникнути плутанини з іншим продуктом компанії – JBoss Enterprise Application Platform.

    WildFly, як і GlassFish, є повноцінним веб-сервером. До речі, під капотом WildFly використовує Tomcat як контейнер сервлетів. На відміну від GlassFish, WildFly більш легкий і простий у налаштуванні.

  3. Jetty – аналогічно попереднім має відкритий вихідний код. Розвивається фірмою Eclipse.

    Як і Tomcat, є простим контейнером сервлетів без підтримки всіх компонентів фреймворку JavaEE. У той же час він легковажніший, і його можна запустити навіть на мобільному телефоні. Він швидко запускається та зупиняється, добре масштабується. На відміну від Tomcat, має менше ком'юніті та базу знань.

  4. WebLogic — ліцензоване програмне забезпечення, яке потребує покупки перед використанням. Належить компанії Oracle.

    У порівнянні з Tomcat, його функціонал трохи ширший. Може працювати з протоколом FTP. Але він не настільки гнучкий при розробці та тестуванні додатків.

  5. WebSphere ( WebSphere Application Server, якщо бути точним) - платне програмне забезпечення. Розробляється компанією IBM. Аналогічно WildFly та GlassFish є повноцінним сервером додатків. Але у нього більш доброзичливий інтерфейс налаштування плюс висока надійність у роботі.

    З мінусів він використовує дуже багато ресурсів, довго запускається і зупиняється, що не дуже зручно при розробці невеликих проектів.

Який контейнер сервлетів чи сервер додатків вибрати залежить від конкретного проекту. Бувають проекти, де навіть явний аутсайдер зможе проявити себе максимально якісно, ​​але спочатку краще якісно розібратися з чимось одним. Напевно, ідеальний кандидат на роль цього одного – Tomcat. Перші кроки у його вивченні ми вже зробабо, а далі справа за тобою! У завершальних статтях циклу "Вступ до Enterprise-розробки" ми з тобою познайомимося з патерном MVC. Частина 7. Знайомство з патерном MVC (Model-View-Controller) Частина 8. Пишемо невелику програму на spring-boot
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ