Читать «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(