void onDataAvailable()
void onAllDataRead()
void onError(Throwable t)
Java Platform, Enterprise Edition (Java EE) 8 Учебник по Java EE |
Назад | Вперёд | Содержание |
Веб-контейнеры на серверах приложений обычно используют отдельный поток сервера для каждого запроса клиента. Для разработки масштабируемых веб-приложений вы должны убедиться, что потоки, связанные с клиентскими запросами, никогда не бездействуют, ожидая завершения операции блокировки. Асинхронная обработка предоставляет механизм для выполнения специфических для приложения операций блокировки в новом потоке, немедленно возвращая поток, связанный с запросом, в контейнер. Даже если вы используете асинхронную обработку для всех специфических для приложения операций блокировки внутри ваших сервисных методов, потоки, связанные с клиентскими запросами, могут мгновение бездействовать в ожидании операций ввода/вывода.
Например, если клиент отправляет большой HTTP запрос POST по медленному сетевому соединению, сервер может прочитать запрос быстрее, чем клиент может его предоставить. При использовании традиционного ввода-вывода поток контейнера, связанный с этим запросом, иногда будет простаивать в ожидании оставшейся части запроса.
Java EE обеспечивает неблокирующую поддержку ввода-вывода для сервлетов и фильтров при обработке запросов в асинхронном режиме. Следующие шаги описывают, как использовать неблокирующий ввод-вывод для обработки запросов и записи ответов внутри сервисных методов.
Переведите запрос в асинхронный режим, как описано в Асинхронная обработка.
Получите входной поток и/или выходной поток из объектов запроса и ответа в сервисном методе.
Назначьте слушатель чтения входному потоку и/или слушатель записи выходному потоку.
Обработайте запрос и ответ внутри Callback-методов слушателя.
Таблица 18-4 и таблица 18-5 описывают методы, доступные во входных и выходных потоках сервлета для поддержки неблокирующего ввода/вывода. Таблица 18-6 описывает интерфейсы для слушателей чтения и записи.
Таблица 18-4. Поддержка неблокирующего ввода-вывода в javax.servlet.ServletInputStream
Метод |
Описание |
|
Связывает данный входной поток с объектом слушателя, который содержит Callback-методы для асинхронного чтения данных. Вы предоставляете объект слушателя как анонимный класс или используете другой механизм для передачи входного потока в объект слушателя чтения. |
|
Возвращает true, если данные могут быть прочитаны без блокировки. |
|
Возвращает true, когда все данные были прочитаны. |
Таблица 18-5. Поддержка неблокирующего ввода-вывода в javax.servlet.ServletOutputStream
Метод |
Описание |
|
Связывает данный выходной поток с объектом слушателя, который содержит Callback-методы для асинхронной записи данных. Вы предоставляете объект слушателя записи как анонимный класс или используете другой механизм для передачи потока вывода объекту слушателя записи. |
|
Возвращает true, если данные могут быть записаны без блокировки. |
Таблица 18-6 Интерфейсы слушателей для поддержки неблокирующего ввода-вывода
Интерфейс |
Методы |
Описание |
|
|
Объект |
|
|
Объект |
Код в этом разделе показывает, как прочитать большой HTTP POST-запрос внутри сервлета, переведя запрос в асинхронный режим (как описано в Асинхронная обработка) и используя функцию неблокирующего ввода-вывода из таблицы 18-4 и таблицы 18-6.
@WebServlet(urlPatterns={"/asyncioservlet"}, asyncSupported=true)
public class AsyncIOServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException {
final AsyncContext acontext = request.startAsync();
final ServletInputStream input = request.getInputStream();
input.setReadListener(new ReadListener() {
byte buffer[] = new byte[4*1024];
StringBuilder sbuilder = new StringBuilder();
@Override
public void onDataAvailable() {
try {
do {
int length = input.read(buffer);
sbuilder.append(new String(buffer, 0, length));
} while(input.isReady());
} catch (IOException ex) { ... }
}
@Override
public void onAllDataRead() {
try {
acontext.getResponse().getWriter()
.write("...the response...");
} catch (IOException ex) { ... }
acontext.complete();
}
@Override
public void onError(Throwable t) { ... }
});
}
}
В этом примере объявляется веб-сервлет с асинхронной поддержкой с использованием параметра аннотации @WebServlet
asyncSupported=true
. Сервисный метод сначала переводит запрос в асинхронный режим, вызывая метод startAsync()
объекта запроса, который необходим для использования неблокирующего ввода-вывода. Затем сервисный метод получает входной поток, связанный с запросом, и назначает слушатель чтения, определённый как внутренний класс. Слушатель читает части запроса, когда они становятся доступными, и затем записывает некоторый ответ клиенту, когда он заканчивает чтение запроса.
Назад | Вперёд | Содержание |