Рубрики
Без рубрики

Введение в сервлеты и контейнеры сервлетов

Изучите концепции, связанные с сервлетами, их контейнерами и несколькими основными объектами, вокруг которых они вращаются.

Автор оригинала: baeldung.

1. Обзор

В этом уроке мы концептуально поймем, что такое сервлеты и контейнеры сервлетов и как они работают .

Мы также увидим их в контексте запроса, ответа, объектов сеанса, общих переменных и многопоточности.

2. Что такое Сервлеты и их Контейнеры

Сервлеты являются компонентом фреймворка JEE, используемого для веб – разработки. В основном это Java-программы, которые выполняются внутри границ контейнера. В целом, они несут ответственность за принятие запроса, его обработку и отправку ответа обратно . Введение в Java-сервлеты обеспечивает хорошее базовое понимание предмета.

Чтобы использовать их, сервлеты должны быть сначала зарегистрированы , чтобы контейнер, основанный на JEE или Spring, мог забрать их при запуске. В начале контейнер создает экземпляр сервлета, вызывая его метод init () .

Как только его инициализация завершена, сервлет готов принимать входящие запросы. Впоследствии контейнер направляет эти запросы для обработки в методе сервлета service () . После этого он далее делегирует запрос соответствующему методу, такому как doGet() или doPost () , в зависимости от типа HTTP-запроса.

С помощью destroy () контейнер разрывает сервлет , и он больше не может принимать входящие запросы. Мы называем этот цикл init-service-destroy жизненным циклом сервлета .

Теперь давайте посмотрим на это с точки зрения контейнера, такого как Apache Tomcat или Jetty . При запуске он создает объект ServletContext . Задача ServletContext состоит в том, чтобы функционировать в качестве памяти сервера или контейнера и запоминать все сервлеты, фильтры и прослушиватели, связанные с веб-приложением, как описано в его web.xml или эквивалентные аннотации. Пока мы не остановим или не завершим контейнер, ServletContext останется с ним.

Однако здесь важную роль играет параметр servlet load-on-startup . Если этот параметр имеет значение больше нуля, только тогда, когда сервер инициализирует его при запуске. Если этот параметр не указан, то init() сервлета вызывается, когда запрос попадает в него в первый раз.

3. Запрос, Ответ и сеанс

В предыдущем разделе мы говорили об отправке запросов и получении ответов, что в основном является краеугольным камнем любого клиент-серверного приложения. Теперь давайте рассмотрим их подробно в отношении сервлетов.

В этом случае запрос будет представлен HttpServletRequest , а ответ – HttpServletResponse .

Всякий раз, когда клиент, такой как браузер или команда curl, отправляет запрос, контейнер создает новый объект HttpServletRequest и HttpServletResponse . Затем он передает эти новые объекты в метод service сервлета. На основе атрибута метода HttpServletRequest этот метод определяет, какой из методов doXXX должен быть вызван.

Помимо информации о методе, объект запроса также содержит другую информацию, такую как заголовки, параметры и тело. Аналогично, объект HttpServletResponse также содержит заголовки, параметры и тело – мы можем настроить их в методе doXXX нашего сервлета.

Эти объекты недолговечны . Когда клиент получает ответ обратно, сервер помечает объекты запроса и ответа для сборки мусора.

Как бы мы тогда поддерживали состояние между последующими клиентскими запросами или подключениями? HttpSession является ответом на эту загадку.

Это в основном привязывает объекты к сеансу пользователя, так что информация, относящаяся к конкретному пользователю, может сохраняться в нескольких запросах. Обычно это достигается с помощью концепции файлов cookie, используя JSESSIONID в качестве уникального идентификатора для данного сеанса. Мы можем указать тайм-аут для сеанса в web.xml :


    10

Это означает, что если ваш сеанс простаивал в течение 10 минут, сервер откажется от него. Любой последующий запрос приведет к созданию нового сеанса.

4. Как Сервлеты Обмениваются Данными

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

Как мы видели в предыдущих разделах, разные объекты имеют разное время жизни. HttpServletRequest и HttpServletResponse объекты живут только между одним вызовом сервлета. HttpSession живет до тех пор, пока он активен и не истекло время ожидания.

Срок службы ServletContext самый длинный. Он рождается вместе с веб-приложением и уничтожается только тогда, когда само приложение завершает работу. Поскольку экземпляры сервлета, фильтра и прослушивателя привязаны к контексту, они также живут до тех пор, пока веб-приложение работает и работает.

Следовательно, если наше требование состоит в том, чтобы обмениваться данными между всеми сервлетами, скажем, если мы хотим подсчитать количество посетителей нашего сайта, то мы должны поместить переменную в ServletContext . Если нам нужно поделиться данными в сеансе, мы сохраним их в области сеанса. В этом случае примером может служить имя пользователя.

Наконец, есть область запроса, относящаяся к данным для одного запроса, например полезная нагрузка запроса.

5. Обработка многопоточности

Несколько Объекты HttpServletRequest совместно используют сервлеты друг с другом, так что каждый запрос работает со своим собственным потоком экземпляра сервлета.

Что это фактически означает с точки зрения потокобезопасности, так это то, что мы не должны назначать данные запроса или сеанса в качестве переменной экземпляра сервлета .

Например, давайте рассмотрим этот фрагмент:

public class ExampleThree extends HttpServlet {
    
    private String instanceMessage;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {
        String message = request.getParameter("message");
        instanceMessage = request.getParameter("message");
        request.setAttribute("text", message);
        request.setAttribute("unsafeText", instanceMessage);
        request.getRequestDispatcher("/jsp/ExampleThree.jsp").forward(request, response);
    }
}

В этом случае все запросы в сеансе совместно используют сообщение экземпляра , тогда как сообщение уникально для данного объекта запроса. Следовательно, в случае одновременных запросов данные в сообщении экземпляра могут быть несогласованными.

6. Заключение

В этом уроке мы рассмотрели некоторые концепции, связанные с сервлетами, их контейнерами и несколькими важными объектами, вокруг которых они вращаются|/. Мы также видели, как сервлеты обмениваются данными и как многопоточность влияет на них.

Как всегда, исходный код доступен на GitHub .