Перейти к содержанию

Java Сервлеты

Java-сервлеты. Особенности реализации, ключевые методы, преимущества и недостатки относительно CGI и FastCGI.

серверные компоненты для создания динамических страниц, генерируемых на сервере
работают внутри контейнера сервлетов (например, Apache Tomcat, Jetty, GlassFish)
обрабатывают HTTP-запросы

Клиент отправляет HTTP-запрос
    Веб-сервер перенаправляет запрос в контейнер сервлетов, который управляет жизненным циклом сервлетов
    Контейнер вызывает соответствующий сервлет, передавая данные запроса
    Сервлет обрабатывает запрос и формирует ответ (HTML, JSON...)
    Сервлет отправляет ответ обратно в контейнер -> передает веб-серверу -> клиенту
Чтобы создать сервлет, нужно:
    Создать класс, который наследуется от HttpServlet
    Переопределить методы, такие как doGet() и doPost(), для обработки соответствующих HTTP-запросов
    Зарегистрировать сервлет в файле конфигурации (например, web.xml) или с использованием аннотаций, таких как @WebServlet
Методы Java-сервлетов
    init() — вызывается контейнером сервлетов при инициализации сервлета. Этот метод выполняется один раз при первом запросе к сервлету.
    doGet(HttpServletRequest request, HttpServletResponse response) — обрабатывает GET-запросы.
    doPost(HttpServletRequest request, HttpServletResponse response) — обрабатывает POST-запросы.
    destroy() — вызывается контейнером при завершении работы сервлета. Используется для освобождения ресурсов.
CGI
    Каждый запрос порождает новый процесс
FastCGI
    постоянные процессы, которые обрабатывают несколько запросов
    может использоваться с любым языком программирования
Java-сервлеты
    сервлеты работают в многопоточном режиме
    один экземпляр сервлета для обработки нескольких запросов
    встроенная поддержка HTTP-сессий
    легко переносятся на разные серверы и платформы
    Требуется наличие контейнера, что добавляет дополнительный уровень настройки и управления
    требует значительных ресурсов памяти, особенно для сложных приложений

Контейнеры сервлетов. Жизненный цикл сервлета.

серверная платформа для развертывания и выполнения Java-сервлетов
управляет жизненным циклом сервлетов
обрабатывает запросы и обеспечивает взаимодействие между сервлетами и веб-сервером

Примеры контейнеров сервлетов:
    Apache Tomcat
    Jetty
    GlassFish
    WildFly
Контейнеры сервлетов обеспечивают:
    создание, инициализацию, обработку запросов и уничтожение сервлетов
    принимает HTTP-запросы от клиентов, обрабатывает их, вызывает соответствующий сервлет и отправляет обратно HTTP-ответ
    поддерживают многопоточность, позволяя одному сервлету обслуживать несколько клиентских запросов одновременно
    обеспечивают безопасность, управляя доступом к ресурсам и обрабатывая аутентификацию и авторизацию пользователей
    поддержка сессий
Как работают контейнеры сервлетов?
    Запуск сервера: Контейнер сервлетов запускается и слушает HTTP-запросы на определенном порту.
    Загрузка сервлета: Когда поступает запрос к сервлету, контейнер либо загружает класс сервлета (если он еще не загружен), либо использует уже существующий экземпляр.
    Создание экземпляра сервлета: Контейнер создает экземпляр сервлета (если он не существует) и вызывает метод init().
    Обработка запроса: Для каждого HTTP-запроса контейнер создает новый поток, который вызывает методы doGet() или doPost() сервлета.
    Формирование ответа: Сервлет формирует HTTP-ответ, который контейнер отправляет клиенту.
    Завершение работы: Когда сервер отключается или необходимо освободить ресурсы, контейнер вызывает метод destroy() для уничтожения экземпляра сервлета.

Диспетчеризация запросов в сервлетах. Фильтры сервлетов.

это механизм перенаправления запросов от одного сервлета к другому или на другую страницу

Внутреннее перенаправление (Forward):
    перенаправление запроса на другой сервлет, JSP внутри одного сервера без участия клиента
    браузер не видит этого перенаправления
    RequestDispatcher dispatcher = request.getRequestDispatcher("anotherServlet");
    dispatcher.forward(request, response);
Внешнее перенаправление (Redirect):
    код 302 - перенаправление
    клиент видит изменение URL в адресной строке.
    response.sendRedirect("http://www.example.com");

Фильтры сервлетов — объекты, позволяют перехватывать и модифицировать запросы и ответы до и после их обработки сервлетами
позволяют добавлять кросс-канальные функции, такие как аутентификация, логирование, сжатие, фильтрация контента и кэширование.

Как работают фильтры?
    Клиент отправляет HTTP-запрос
    Фильтр перехватывает запрос, модифицирует его или проверяет
    Запрос передается в сервлет
    Сервлет обрабатывает запрос и формирует ответ
    Фильтр перехватывает ответ перед отправкой клиенту, модифицирует его при необходимости
    Ответ отправляется клиенту
Создание фильтра
    нужно реализовать интерфейс Filter и переопределить три метода:
    init(FilterConfig filterConfig) — инициализация фильтра. Вызывается один раз при создании фильтра.
    doFilter(ServletRequest request, ServletResponse response, FilterChain chain) — основная логика фильтрации. Выполняется при каждом запросе.
    destroy() — уничтожение фильтра, выполняется перед его удалением.

@WebFilter("/myServlet")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Инициализация фильтра
    }
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Логирование запроса перед отправкой в сервлет
        System.out.println("Запрос перед обработкой сервлетом");
        // Передача запроса следующему фильтру или сервлету
        chain.doFilter(request, response);
        // Логирование после обработки запроса
        System.out.println("Ответ после обработки сервлетом");
    }
    @Override
    public void destroy() {
        // Очистка ресурсов при уничтожении фильтра
    }
}

Примеры использования фильтров
    Аутентификация: Проверка, авторизован ли пользователь, и при отсутствии прав доступа — перенаправление на страницу логина.
    Логирование: Логирование информации о каждом запросе (IP-адрес, время, метод запроса).
    Кэширование: Изменение заголовков HTTP-ответа для контроля кэширования контента.
    Сжатие: Сжатие HTTP-ответа для экономии трафика.

HTTP-сессии - назначение, взаимодействие сервлетов с сессией, способы передачи идентификатора сессии.

позволяет сохранять состояние пользователя между несколькими запросами
тк HTTP - stateless, сессии позволяют ассоциировать разные запросы с одним и тем же пользователем
HttpSession session = request.getSession();
session.setAttribute("username", "JohnDoe");
String username = (String) session.getAttribute("username");

Способы передачи идентификатора сессии
Для ассоциации каждого запроса с конкретной сессией используется идентификатор сессии (Session ID)
Этот идентификатор позволяет серверу различать запросы разных пользователей и поддерживать состояние

Контекст сервлета - назначение, способы взаимодействия сервлетов с контекстом.

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

Назначение ServletContext:
    Хранение общих данных: Позволяет хранить данные, которые доступны всем сервлетам в рамках одного веб-приложения.
    Доступ к параметрам конфигурации: Содержит параметры конфигурации, определенные в файле web.xml.
    Логирование: Предоставляет методы для записи логов и ошибок, которые происходят в приложении.
    Доступ к ресурсам: Позволяет сервлетам взаимодействовать с файлами и ресурсами, находящимися в пределах веб-приложения (например, HTML, JSP, текстовые файлы).
    Общение между сервлетами: Используется для обмена данными и взаимодействия между разными сервлетами.
Способы взаимодействия сервлетов с контекстом
    ServletContext context = getServletContext();
    context.setAttribute("sharedData", "This is shared data");
    String sharedData = (String) context.getAttribute("sharedData");

JSP (Java Server Pages)

JavaServer Pages. Особенности, преимущества и недостатки по сравнению с сервлетами, область применения.

для создания динамически генерируемых веб-страниц
отделение логики приложения (Java-код) от его представления (HTML-контент)

JSP автоматически компилируются в сервлеты при первом запуске, что избавляет от необходимости вручную создавать сервлеты

Жизненный цикл JSP.

Жизненный цикл JSP во многом похож на жизненный цикл сервлета, так как JSP в конечном итоге компилируется в сервлет

Основные этапы жизненного цикла JSP выглядят следующим образом:
    контейнер преобразует JSP в Java файл
    контейнер компилирует Java в .class файл (сервлет)
    после успешной компиляции класс сервлета загружается в контейнер
    затем вызывается метод jspInit(), который инициализирует JSP
    после инициализации JSP переходит в состояние готовности к обработке HTTP-запросов
    для каждого запроса вызывается метод jspService(), который обрабатывает запрос и генерирует ответ
    когда контейнер JSP обнаруживает, что JSP больше не нужен или сервер останавливается, он вызывает метод jspDestroy()

Структура JSP-страницы. Комментарии, директивы, объявления, скриптлеты и выражения.

Комментарии 
    <%-- Это комментарий JSP, не попадает в HTML-выход --%>
Директивы 
    <%@ page contentType="text/html; charset=UTF-8" language="java" %>
    <%@ include file="header.jsp" %>
Объявления
    <%!  private int counter = 0;  %>
Скриптлеты - произвольный Java-код
    <% counter++; // Изменение переменной %>
Выражения
    <p>Сообщение: <%= message %></p>

Правила записи Java-кода внутри JSP. Стандартные переменные, доступные в скриптлетах и выражениях.

request
response
session
out.println

Bean-компоненты и их использование в JSP.

JavaBeans — это классические Java-классы, которые следуют определенным соглашениям и
используются для инкапсуляции данных и бизнес-логики в Java-приложениях, включая JSP.
JavaBeans могут содержать свойства, методы доступа (геттеры и сеттеры) и могут быть
легко использованы в JSP для отображения данных и управления состоянием

Основные характеристики JavaBeans
    Конструктор по умолчанию: JavaBean должен иметь публичный конструктор без параметров.
    Приватные свойства: Все свойства (поля) должны быть объявлены как приватные, чтобы обеспечить инкапсуляцию.
    Геттеры и сеттеры: Для доступа к свойствам должны быть определены публичные методы-геттеры и сеттеры.
    Сериализация: JavaBeans могут реализовывать интерфейс Serializable, что позволяет сохранять состояние объекта.

public class User implements Serializable {
    private String name;
    private int age;
    public User() {}
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}

Использование JavaBeans в JSP

JavaBeans могут быть использованы в JSP для передачи данных и отображения их в веб-страниц
отделяет бизнес-логику от представления
JavaBeans — это простые Java-классы, которые используются для управления данными в веб-приложениях. Вот основные причины, зачем они нужны


Создание JavaBean: Как показано выше, создайте класс JavaBean с необходимыми свойствами и методами.
Импортирование JavaBean в JSP: Используйте директиву <%@ page import="..." %> для импорта вашего JavaBean.
Создание и настройка JavaBean: Создайте экземпляр JavaBean и настройте его свойства с помощью скриптлетов или выражений.
Использование тегов JSP: Для доступа к свойствам JavaBean используйте специальные теги, такие как <jsp:useBean>, <jsp:setProperty> и <jsp:getProperty>.

<%@ page import="com.example.User" %>

<jsp:useBean id="user" class="com.example.User" scope="session" />
<jsp:setProperty name="user" property="name" value="Алексей" />
<jsp:setProperty name="user" property="age" value="30" />

<p>Имя: <jsp:getProperty name="user" property="name" /></p>
<p>Возраст: <jsp:getProperty name="user" property="age" /></p>

Стандартные теги JSP. Использование Expression Language (EL) в JSP.

JSP (JavaServer Pages) предоставляет стандартные теги и возможности использования Expression Language (EL)
для упрощения работы с данными и динамическим контентом на веб-страницах

Стандартные теги JSP
<jsp:useBean>:
<jsp:useBean id="user" class="com.example.User" scope="session" />
<jsp:setProperty>:
<jsp:setProperty name="user" property="name" value="Алексей" />
<jsp:getProperty>:
<p>Имя: <jsp:getProperty name="user" property="name" /></p>
<jsp:include>:
<jsp:include page="header.jsp" />
<jsp:forward>:
<jsp:forward page="welcome.jsp" />


Использование Expression Language (EL) в JSP
Expression Language (EL) — это упрощенный способ доступа к данным, хранящимся в объектах, таких
как JavaBeans, коллекции и атрибуты сессии

Пример JSP с использованием стандартных тегов и EL
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<jsp:useBean id="user" class="com.example.User" scope="session" />
<jsp:setProperty name="user" property="name" value="Алексей" />
<jsp:setProperty name="user" property="age" value="30" />

<html>
<head>
    <title>Пример JSP с EL и стандартными тегами</title>
</head>
<body>
    <h2>Информация о пользователе:</h2>
    <p>Имя: ${user.name}</p>
    <p>Возраст: ${user.age}</p>

    <c:if test="${user.age >= 18}">
        <p>Вы совершеннолетний.</p>
    </c:if>

    <h3>Список покупок:</h3>
    <c:forEach var="item" items="${shoppingList}">
        <p>${item.name}</p>
    </c:forEach>
</body>
</html>

Параметры конфигурации JSP в дескрипторе развёртывания веб-приложения.

конфигурация web.xml

Основные параметры конфигурации JSP в web.xml

<context-param>
    <param-name>appName</param-name>
    <param-value>My Web Application</param-value>
</context-param>

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
    <init-param>
        <param-name>maxUsers</param-name>
        <param-value>100</param-value>
    </init-param>
</servlet>

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Параметры JSP в jsp-config
    Внутри элемента <jsp-config> могут быть указаны специфические настройки для всех JSP-страниц приложения:
    <jsp-property-group>: Группирует параметры для нескольких JSP-страниц, чтобы избежать дублирования. Он может содержать следующие параметры:
    <url-pattern>: Определяет шаблон URL для сопоставления с данной группой параметров.
    <el-ignored>: Указывает, нужно ли игнорировать выражения EL.
    <scripting-invalid>: Определяет, допустимо ли использование скриптлетов в JSP.
    <is-xml>: Указывает, является ли JSP-страница XML-совместимой.
    <trim-directive-whitespaces>: Определяет, следует ли удалять пробелы в директивах JSP.