Читать «Java 7 (Наиболее полное руководство)» онлайн - страница 424

Ильдар Шаукатович Хабибуллин

После выполнения метода include () управление возвращается в сервлет.

Асинхронное выполнение запросов

Если несколько запросов приходят одновременно, контейнер сервлетов создает подпроцессы, выполняющие метод service () для каждого запроса. Количество подпроцессов может оказаться слишком велико, а время их работы может затянуться, особенно если сервлет ожидает получение данных из базы данных или из файла или окончания длительной обработки информации. В этом случае необходимо обеспечить быстроту работы сервлета. Этого можно достигнуть, выполняя запросы асинхронно: сервлет принимает запрос, передает его обработку асинхронному подпроцессу и завершает работу, не дожидаясь ответа от этого подпроцесса. Асинхронный подпроцесс сам формирует ответ или передает управление другому сервлету в итоге выполнения своей работы.

Такая возможность предоставлена сервлетам и фильтрам, начиная с версии 3.0.

Сервлет или фильтр, выполняющий асинхронную работу, отмечается в конфигурационном файле web.xml элементом <async-supported> со значением true или в аннотациях

@WebServlet, @WebFilter параметром asyncSupported, например,

@WebServlet(value="/MyAsyncServlet", asyncSupported="true")

Возможность выполнения асинхронных действий можно проверить методом

isAsyncSupported().

Асинхронная обработка запроса начинается обращением к методу startAsync () объекта типа ServletRequest, в который передаются ссылки на запрос ServletRequest и ответ ServletResponse. Этот метод возвращает ссылку на объект типа AsyncContext, методы которого позволяют проследить за работой асинхронного метода. Проверить, что запрос обрабатывается асинхронно, можно логическим методом isAsyncStarted ( ).

После выполнения метода startAsync() обработка запроса будет завершена не по окончании работы метода service(), как обычно, а методом complete() объекта AsyncContext или по прошествии времени, заданного предварительно методом setTimeout (). Кроме того, можно создать объект типа AsyncListener и его методами отследить этапы асинхронной обработки.

Интерфейс AsyncListener описывает четыре метода: onStartAsync( ), onError(), onComplete () и onTimeout (). Реализовав эти методы, можно отреагировать на наступление соответствующих четырех событий.

Асинхронную работу естественно выполнять в отдельном подпроцессе.

В листинге 26.8 приведен типичный пример асинхронного сервлета. Обратиться к нему можно примерно так:

После набора этого адреса в адресной строке браузера, подождите 10 секунд, и вы увидите ответ сервлета.

Листинг 26.8. Асинхронный сервлет

package mypack;

import java.io.*;

import java.util.concurrent.*;

import javax.servlet.*;

import javax.servlet.annotation.*;

import javax.servlet.http.*;

import java.util.Date;

@WebServlet(urlPatterns = "/AsyncServlet", asyncSupported=true) public class AsyncServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (!request.isAsyncSupported()){ response.getWriter().println(