Асинхронные сервлеты Java

Асинхронные сервлеты JavaДо сих пор вы видели, что можете преобразовать любой метод компонента в асин­хронный метод. Теперь вы увидите, как заставить асинхронно функционировать
сервлет. Без наличия асинхронной поддержки в сервлетах нелегко отвечать требо­ваниям асинхронности при веб-разработке.

Спецификация Servlet 3.0 (JSR 315) внесла серьезные усовершенствования в интерфейсы программирования веб-приложений (API) языка Jаvа. С появлени­ем JSR 315 спецификации сервлетов были обновлены (после длительного ожида­ния) для поддержки асинхронной модели выполнения, удобной конфигурации, подключаемости и других мелких улучшений.

Асинхронные сервлеты основываются на ключевом усовершенствовании в HyperText Traпsfer Protocol (НТТР) 1.1, сделавшем возможными постоянные со­единения. В НТТР 1.0 каждое соединение использовалось для отправки и получения только одной пары «запрос/ответ«; в то же время НТТР 1.1 позволяет веб-приложе­ниям поддерживать соединение в активном состоянии и посылать множественные запросы.

При стандартной реализации прикладная часть Java потребовала бы от­дельного потока, постоянно прикрепленного к НТТР-соединению. Однако небло­кирующее API ввода-вывода языка Java (Java Nonblocking I/O, NIO) возвращает между активными запросами потоки «в оборот» благодаря новым возможностям NIO. На сегодняшний день все совместимые со спецификациями Servlet 3.0 веб­ серверы имеют встроенную поддержку Java NIO.

Асинхронные сервлеты JavaДля чего вам может понадобиться от сервлетов подобное поведение? Для сер­верных систем характерны длительные операции, такие как соединение с другими серверами, выполнение сложных вычислений и осуществление операций транзак­ционных баз данных. Однако сущность веб-страниц требует как раз обратного.

Веб-пользователи ожидают короткого времени отклика и UI, функционирующего даже в случае незавершенных операций серверной части. AJАХ взял на себя ре­шение этой проблемы для браузеров и начал революцию Web 2.0.

Спецификация Servlet 3.0 предоставила метод startAsync(), сделавший доступными асинхронные операции. Следующий пример кода показывает пример этого:

Сервлет выводит Results: и далее выводит полученные из базы данные, кото­рыми в этом сценарии является простая строка. Вам необходимо инициализировать отдельный поток.

Метод onComplete класса Asynclistener выполняется только после завершения выполнения. В классе Asynclistener есть еще несколько методов жиз­ненного цикла.

  • OnStartAsync — выполняется при запуске асинхронного контекста;
  • OnTimeOut — выполняется, только если истекает время ожидания;
  • onError — выполняется, только если была получена ошибка.

Спецификация Servlet 3.1 предоставляет более простой способ реализации асинхронных сервлетов путем использования управляемых пулов потоков и сер­виса выполнения.

В следующем примере задействуется ManagedThreadFactory для создания нового потока.

Этот пример создает новый поток с процессом, требующим больших затрат времени, и наконец вызывает функцию complete из asyncContext. ManagedThreadFactory служит в качестве доступного потока из пула, который вам необходимо запустить явным образом.

Другой подход состоит в передаче ManagedExecutorServiсе асинхронного Runnable вместо создания и последующего запуска потока в сервлете. Делегирование ExecutorServiсе вопросов организации поточной обработки обеспечивает более «чистый» код, как вы увидите в следующем примере:

Хотя это всего лишь на одну строку меньше, чем в предыдущем примере, программа делегирует создание и запуск потока ExecutorServiсе и имеет дело только с сервлетным кодом.

Асинхронные сервлеты легче для понимания и программирования и оказывают немедленный эффект на динамическое поведение, поскольку напрямую «переклю­чают» на модель асинхронного выполнения. Асинхронные сервлеты обеспечивают «чистую» реализацию без большого количества шаблонного кода.