---
title: Сервлеты
seo:
  title: Сервлеты — Java Developer
  description: Тема «Сервлеты» для собеседования Java Developer. Что такое «сервлет»? В чем заключаются преимущества технологии сервлетов над CGI (Common Gateway Interface)?
---

[Все темы Java Developer](/java-developer)

## <strong>Что такое «сервлет»?</strong> [#q-14bee738d69b8139b476d50788f58217]

Сервлет представляет серверный компонент для обработки запросов; жизненным циклом управляет контейнер. Технология развивается в Jakarta Servlet. Примеры ниже используют прежнее пространство имён javax.servlet из Java EE; начиная с Jakarta Servlet 5 используется jakarta.servlet.

Основные особенности сервлетов&#58;

1. <strong>Обработка HTTP-запросов</strong>&#58; Сервлеты могут обрабатывать
   различные HTTP-запросы (GET, POST и т.д.).

1. <strong>Жизненный цикл</strong>&#58; Жизненный цикл сервлета управляется
   контейнером сервлетов (например, Apache Tomcat) и включает этапы
   инициализации (<code>init</code>), обработки запросов (<code>service</code>)
   и уничтожения (<code>destroy</code>).

1. <strong>Динамическое создание контента</strong>&#58; Сервлеты могут
   генерировать динамический контент, такой как HTML, JSON, XML и другие
   форматы.

Пример простого сервлета&#58;

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

public class HelloWorldServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.getWriter().println("<h1>Hello, World!</h1>");
    }
}
```

В этом примере сервлет <code>HelloWorldServlet</code> обрабатывает HTTP GET запросы и возвращает простой HTML-ответ "Hello, World!".

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>В чем заключаются преимущества технологии сервлетов над</strong> <code>CGI</code> <strong>(Common Gateway Interface)?</strong> [#q-14bee738d69b81858ab8fb989d34f893]

Преимущества технологии сервлетов над <code>CGI</code> (Common Gateway Interface)&#58;

{/* prettier-ignore */}
1. <strong>Производительность</strong>&#58;

    - <strong>Сервлеты</strong>&#58; Загружаются в память один раз и остаются в ней, обслуживая множество запросов. Это снижает накладные расходы на создание процессов для каждого запроса.

    - <strong>CGI</strong>&#58; Для каждого запроса создается новый процесс, что увеличивает накладные расходы и снижает производительность.

1. <strong>Многопоточность</strong>&#58;

    - <strong>Сервлеты</strong>&#58; Используют многопоточность, что позволяет обрабатывать множество запросов параллельно в одном процессе.

    - <strong>CGI</strong>&#58; Каждый запрос запускается в отдельном процессе, что менее эффективно.

1. <strong>Управление памятью</strong>&#58;

    - <strong>Сервлеты</strong>&#58; Управляются JVM (Java Virtual Machine), что позволяет использовать механизмы управления памятью, такие как сборка мусора.

    - <strong>CGI</strong>&#58; Управление памятью и ресурсами зависит от операционной системы, что может приводить к более высокому потреблению ресурсов.

1. <strong>Безопасность</strong>&#58;

    - <strong>Сервлеты</strong>&#58; Могут использовать мощные встроенные механизмы безопасности Java, включая контроль доступа и обработку исключений.

    - <strong>CGI</strong>&#58; Менее гибкие и безопасные, требуют дополнительной настройки для обеспечения безопасности.

1. <strong>Переносимость</strong>&#58;

    - <strong>Сервлеты</strong>&#58; Написаны на Java, что обеспечивает переносимость между различными платформами и серверами приложений.

    - <strong>CGI</strong>&#58; Скрипты зависят от языка программирования и платформы, на которой они выполняются, что может ограничивать переносимость.

1. <strong>Легкость разработки и обслуживания</strong>&#58;

    - <strong>Сервлеты</strong>&#58; Предоставляют богатый API и поддержку различных средств разработки, что упрощает создание и сопровождение веб-приложений.

    - <strong>CGI</strong>&#58; Написание и обслуживание CGI-скриптов может быть более сложным из-за ограниченных возможностей и инструментов.

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>Какова структура веб-проекта?</strong> [#q-14bee738d69b815f858ac628beab5536]

Структура веб-проекта обычно включает следующие основные компоненты&#58;

{/* prettier-ignore */}
1. <strong>Исходный код</strong>&#58;

    - <strong>Java-классы</strong>&#58; Контроллеры, сервисы, DAO (Data Access Objects), модели.

    - <strong>Сервлеты</strong>&#58; Классы, обрабатывающие запросы.

1. <strong>Ресурсы</strong>&#58;

    - <strong>Статические ресурсы</strong>&#58; HTML, CSS, JavaScript, изображения и другие статические файлы.

    - <strong>Шаблоны</strong>&#58; Файлы шаблонов для динамического формирования HTML (например, JSP, Thymeleaf).

1. <strong>Конфигурация</strong>&#58;

    - <strong>web.xml</strong>&#58; Файл конфигурации веб-приложения (указывается маппинг сервлетов, фильтры и другие параметры).

    - <strong>application.properties</strong> или <strong>application.yml</strong>&#58; Файлы конфигурации параметров приложения (например, для Spring Boot).

    - <strong>context.xml</strong> или <strong>server.xml</strong>&#58; Файлы конфигурации сервера (например, для Apache Tomcat).

1. <strong>Библиотеки</strong>&#58;

    - <strong>JAR-файлы</strong>&#58; Зависимости и библиотеки, используемые в проекте.

1. <strong>Тесты</strong>&#58;

    - <strong>Unit-тесты</strong>&#58; Тесты для проверки отдельных компонентов.

    - <strong>Integration-тесты</strong>&#58; Тесты для проверки взаимодействия между компонентами.

1. <strong>Средства сборки</strong>&#58;

    - <strong>build.gradle</strong> или <strong>pom.xml</strong>&#58; Скрипты сборки и управления зависимостями (например, для Gradle или Maven).

Пример структуры веб-проекта на Java (<code>Maven</code>)&#58;

```java
my-webapp/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           ├── controller/
│   │   │           ├── service/
│   │   │           ├── dao/
│   │   │           └── model/
│   │   ├── resources/
│   │   │   ├── application.properties
│   │   │   └── messages.properties
│   │   ├── webapp/
│   │   │   ├── WEB-INF/
│   │   │   │   ├── web.xml
│   │   │   │   └── views/
│   │   │   │       └── index.jsp
│   │   │   ├── css/
│   │   │   ├── js/
│   │   │   └── images/
│   ├── test/
│   │   └── java/
│   │       └── com/
│   │           └── example/
│   │               ├── controller/
│   │               ├── service/
│   │               ├── dao/
│   │               └── model/
└── pom.xml
```

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>Что такое «контейнер сервлетов»?</strong> [#q-14bee738d69b81528ad9eee2f32daf63]

<strong>Контейнер сервлетов</strong> — это компонент веб-сервера или сервера
приложений, который управляет жизненным циклом сервлетов, обрабатывает их
запросы и предоставляет необходимые ресурсы и услуги.

Основные функции контейнера сервлетов&#58;

1. <strong>Управление жизненным циклом</strong>&#58; Инициализация, обработка
   запросов и уничтожение сервлетов.

1. <strong>Обработка запросов и ответов</strong>&#58; Прием HTTP-запросов от
   клиентов, передача их сервлетам и отправка HTTP-ответов обратно клиентам.

1. <strong>Безопасность</strong>&#58; Управление безопасностью приложений,
   аутентификация и авторизация пользователей.

1. <strong>Управление ресурсами</strong>&#58; Обеспечение доступа к ресурсам,
   таким как базы данных, файлы и внешние службы.

1. <strong>Конфигурация и деплоймент</strong>&#58; Обработка конфигурационных
   файлов (например, <code>web&#46;xml</code>), управление настройками и
   развертывание веб-приложений.

Примеры контейнеров сервлетов&#58;

- <strong>Apache Tomcat</strong>

- <strong>Jetty</strong>

- <strong>GlassFish</strong>

- <strong>WildFly</strong>

Контейнер сервлетов играет ключевую роль в функционировании веб-приложений, обеспечивая их стабильность, безопасность и масштабируемость.

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>Что такое «дескриптор развертывания»?</strong> [#q-14bee738d69b81e0b4dae6b7bb00362e]

<strong>Дескриптор развертывания</strong> — это XML-файл, используемый для
конфигурации веб-приложения в контейнере сервлетов. Он содержит метаданные,
которые описывают, как веб-приложение должно быть развернуто и как оно должно
функционировать. В дескрипторе развертывания указываются различные параметры,
такие как маппинг сервлетов, фильтры, параметры инициализации, роли безопасности
и многое другое.

Основной дескриптор развертывания для Java веб-приложений называется <code>web&#46;xml</code> и находится в директории <code>WEB&#45;INF</code> веб-приложения.

Пример содержимого <code>web&#46;xml</code>&#58;

```xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <servlet>
        <servlet-name>HelloServlet</servlet-name>
        <servlet-class>com.example.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloServlet</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>LoggingFilter</filter-name>
        <filter-class>com.example.LoggingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>LoggingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <context-param>
        <param-name>maxUsers</param-name>
        <param-value>100</param-value>
    </context-param>

    <listener>
        <listener-class>com.example.AppListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Protected Area</web-resource-name>
            <url-pattern>/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/login.html</form-login-page>
            <form-error-page>/error.html</form-error-page>
        </form-login-config>
    </login-config>

    <security-role>
        <role-name>admin</role-name>
    </security-role>

</web-app>
```

В этом примере дескриптор развертывания <code>web&#46;xml</code> описывает&#58;

- Сервлет <code>HelloServlet</code> и его маппинг на URL <code>&#47;hello</code>.

- Фильтр <code>LoggingFilter</code>, который применяется ко всем URL (<code>&#47;\*</code>).

- Параметр контекста <code>maxUsers</code> с значением <code>100</code>.

- Листенер <code>AppListener</code>.

- Список файлов приветствия (<code>index&#46;html</code> и <code>index&#46;jsp</code>).

- Конфигурацию безопасности для защищенной области <code>&#47;admin&#47;\*</code>, которая требует роль <code>admin</code>.

- Конфигурацию формы логина и безопасности.

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>В каком случае требуется переопределять метод</strong> <code>service&#40;&#41;</code><strong>?</strong> [#q-14bee738d69b8199a4e7f4b31e839232]

Переопределять метод <code>service&#40;&#41;</code> требуется в тех случаях, когда необходимо кастомизировать обработку всех типов HTTP-запросов (GET, POST, PUT, DELETE и т.д.) в одном методе. Метод <code>service&#40;&#41;</code> отвечает за распределение входящих запросов к соответствующим методам (<code>doGet&#40;&#41;</code>, <code>doPost&#40;&#41;</code>, <code>doPut&#40;&#41;</code>, <code>doDelete&#40;&#41;</code> и т.д.) сервлета.

Основные случаи, когда может потребоваться переопределение метода <code>service&#40;&#41;</code>&#58;

1. <strong>Универсальная обработка логики</strong>&#58; Когда нужно выполнить
   общую логику для всех типов запросов до или после их обработки.

1. <strong>Альтернативное распределение запросов</strong>&#58; Когда требуется
   нестандартная маршрутизация или дополнительная логика распределения запросов.

1. Обработка специальных HTTP-методов&#58; HttpServlet уже поддерживает OPTIONS и TRACE через doOptions и doTrace. Переопределение service может понадобиться для нестандартной диспетчеризации; для общей предобработки часто подходит Filter.

Пример переопределения метода <code>service&#40;&#41;</code>&#58;

```java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class CustomServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // Общая логика для всех типов запросов
        System.out.println("Request received");

        // Вызываем родительский метод для стандартной обработки
        super.service(req, resp);

        // Логика после обработки запроса
        System.out.println("Response sent");
    }
}
```

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## Почему обычно переопределяют init() без аргументов в GenericServlet? [#q-14bee738d69b81e3ab0eed0d331956a7]

Контейнер вызывает Servlet.init(ServletConfig). Реализация GenericServlet сохраняет конфигурацию и затем вызывает удобный hook init() без аргументов. Обычно переопределяют этот hook. Если переопределён init(ServletConfig), вызов super.init(config) сохраняет базовую инициализацию.

Основные причины переопределения метода <code>init&#40;&#41;</code> без аргументов&#58;

1. <strong>Инициализация ресурсов</strong>&#58; Метод
   <code>init&#40;&#41;</code> используется для выполнения инициализации
   ресурсов, необходимых для работы сервлета (например, подключение к базе
   данных, настройка параметров).

1. <strong>Упрощение кода</strong>&#58; Переопределение метода без аргументов
   позволяет сосредоточиться на логике инициализации, не отвлекаясь на детали
   инициализации, переданные через <code>ServletConfig</code>.

1. Совместимость&#58; init() без аргументов сохраняет стандартную работу GenericServlet.init(ServletConfig), включая сохранение ServletConfig.

Пример переопределения метода <code>init&#40;&#41;</code>&#58;

```java
import javax.servlet.*;
import javax.servlet.http.*;

public class MyServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        // Инициализация ресурсов
        System.out.println("Servlet is being initialized");
    }
}
```

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>Что вы знаете о сервлетных фильтрах?</strong> [#q-14bee738d69b819cbb83fd67699a6a7e]

<strong>Сервлетные фильтры</strong> — это компоненты веб-приложения, которые
позволяют перехватывать и изменять запросы и ответы в сервлетах. Они
предоставляют механизм для выполнения предобработки и постобработки запросов и
ответов.

Основные особенности сервлетных фильтров&#58;

1. <strong>Предобработка и постобработка</strong>&#58; Фильтры могут выполнять
   действия перед тем, как запрос достигнет сервлета, и после того, как сервлет
   обработает запрос и сформирует ответ.

1. <strong>Цепочка фильтров</strong>&#58; Несколько фильтров могут быть связаны
   в цепочку, где каждый фильтр может передать управление следующему фильтру или
   конечному сервлету.

1. <strong>Переиспользование кода</strong>&#58; Фильтры позволяют
   переиспользовать код для общих задач, таких как аутентификация, логирование,
   сжатие данных и т.д.

Пример фильтра, который логирует все запросы&#58;

```java
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;

public class LoggingFilter implements Filter {
    public void init(FilterConfig filterConfig) throws ServletException {
        // Инициализация фильтра
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        System.out.println("Request URI: " + httpRequest.getRequestURI());

        // Передача управления следующему фильтру или сервлету
        chain.doFilter(request, response);
    }

    public void destroy() {
        // Очистка ресурсов
    }
}
```

В этом примере фильтр <code>LoggingFilter</code> перехватывает каждый запрос, логирует его URI и затем передает управление следующему элементу цепочки (другому фильтру или сервлету) с помощью метода <code>chain&#46;doFilter&#40;&#41;</code>.

Фильтры конфигурируются в дескрипторе развертывания <code>web&#46;xml</code> или с помощью аннотаций&#58;

```xml
<filter>
    <filter-name>LoggingFilter</filter-name>
    <filter-class>com.example.LoggingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>LoggingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
```

Или с помощью аннотаций&#58;

```java
import javax.servlet.annotation.WebFilter;

@WebFilter("/*")
public class LoggingFilter implements Filter {
    // методы фильтра
}
```

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::

---

## <strong>Как реализовать запуск сервлета одновременно с запуском приложения?</strong> [#q-14bee738d69b81549d67e665c619a51f]

Для реализации запуска сервлета одновременно с запуском приложения, можно использовать параметр <code>load&#45;on&#45;startup</code> в дескрипторе развертывания <code>web&#46;xml</code>. Этот параметр указывает контейнеру сервлетов инициализировать и загружать сервлет при старте приложения, а не при первом запросе к нему.

Пример конфигурации <code>web&#46;xml</code>&#58;

```xml
<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.example.MyServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/myservlet</url-pattern>
</servlet-mapping>
```

В этом примере <code>MyServlet</code> будет загружен и инициализирован при старте приложения. Значение <code>1</code> в элементе <code>load&#45;on&#45;startup</code> задает порядок загрузки сервлетов. Сервлеты с меньшими значениями загружаются раньше. Положительное значение (например, <code>1</code>) указывает на необходимость загрузки при старте, тогда как отрицательное значение или его отсутствие означает, что сервлет будет загружен при первом запросе к нему.

Если используются аннотации, можно добавить аннотацию <code>&#64;WebServlet</code> и указать параметр <code>loadOnStartup</code>&#58;

```java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

@WebServlet(urlPatterns = "/myservlet", loadOnStartup = 1)
public class MyServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        super.init();
        // Код инициализации сервлета
        System.out.println("MyServlet is initialized");
    }
}
```

В этом примере сервлет <code>MyServlet</code> также будет загружен при старте приложения благодаря параметру <code>loadOnStartup &#61; 1</code> в аннотации <code>&#64;WebServlet</code>.

:::note[Ссылки для изучения]

1. [Сервлеты в Java](https://javarush.com/groups/posts/2529-chastjh-5-servletih-pishem-prostoe-veb-prilozhenie)
   :::
