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

В жизненном цикле сервлета центральное место занимают три метода. Это init(), service() и destroy(). Они реализуются каждым сервлетом и вызываются сервером в определенное время.

  • На этапе инициализации жизненного цикла сервлета веб-контейнер инициализирует экземпляр сервлета, вызывая метод init(), передавая объект, реализующий интерфейс javax.servlet.ServletConfig. Этот объект конфигурации позволяет сервлету получать доступ к параметрам инициализации значения имени из веб-приложения.
  • После инициализации экземпляр сервлета может обслуживать запросы клиентов. Каждый запрос обслуживается в отдельном потоке. Веб-контейнер вызывает метод сервлета service() для каждого запроса. Метод service() определяет тип выполняемого запроса и отправляет его соответствующему методу для обработки запроса. Разработчик сервлета должен предоставить реализацию для этих методов. Если запрос сделан для метода, который не реализован сервлетом, вызывается метод родительского класса, что обычно приводит к возврату ошибки запрашивающей стороне.
  • Наконец, веб-контейнер вызывает метод destroy(), который выводит сервлет из строя. Метод destroy(), как и init(), вызывается только один раз в жизненном цикле сервлета.

Ниже приведен типичный сценарий использования этих методов пользователем.

  1. Предположим, что пользователь запрашивает посещение URL-адреса.
    • Затем браузер генерирует HTTP-запрос для этого URL-адреса.
    • Затем этот запрос отправляется на соответствующий сервер.
  2. HTTP-запрос принимается веб-сервером и пересылается в контейнер сервлета.
    • Контейнер отображает этот запрос на конкретный сервлет.
    • Сервлет динамически извлекается и загружается в адресное пространство контейнера.
  3. Контейнер вызывает метод init() сервлета.
    • Этот метод вызывается только при первой загрузке сервлета в память.
    • Сервлету можно передать параметры инициализации, чтобы он мог настроить себя.
  4. Контейнер вызывает метод сервлета service().
    • Этот метод вызывается для обработки HTTP-запроса.
    • Сервлет может читать данные, предоставленные в HTTP-запросе.
    • Сервлет также может формировать HTTP-ответ для клиента.
  5. Сервлет остается в адресном пространстве контейнера и доступен для обработки любых других HTTP-запросов, полученных от клиентов.
    • Метод service() вызывается для каждого HTTP-запроса.
  6. В какой-то момент контейнер может решить выгрузить сервлет из своей памяти.
    • Алгоритмы, по которым принимается это решение, индивидуальны для каждого контейнера.
  7. Контейнер вызывает метод destroy() сервлета, чтобы освободить любые ресурсы, такие как дескрипторы файлов, которые выделены для сервлета; важные данные могут быть сохранены в постоянном хранилище.
  8. Затем память, выделенная для сервлета и его объектов, может быть удалена сборщиком мусора.

Пример сервлета

В следующем примере сервлет печатает, сколько раз был вызван его метод service().

Обратите внимание, что HttpServlet является подклассом GenericServlet, реализацией интерфейса Servlet.

Метод service() класса HttpServlet отправляет запросы к методам doGet(), doPost(), doPut(), doDelete() и так далее; согласно HTTP-запросу. В приведенном ниже примере service() переопределяется и не определяет, какой метод HTTP-запроса он обслуживает.

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

public class ServletLifeCycleExample extends HttpServlet {
 
    private Integer sharedCounter;                 
 
    @Override
    public void init(final ServletConfig config) throws ServletException {
        super.init(config);
        getServletContext().log("init() вызван");
        sharedCounter = 0;
    }

    
    @Override
    protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        getServletContext().log("service() вызван");

        int localCounter;                       

        synchronized (sharedCounter) {
              sharedCounter++;                  

              localCounter = sharedCounter;       
        }

        // доступ к локальной переменной
        response.getWriter().write("Увеличение счетчика до " + localCounter);  
    }
 
    @Override
    public void destroy() {
        getServletContext().log("destroy() вызван");
    }
}


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки