Завершение HttpServletResponse, но продолжить обработку
У меня есть ситуация, которая, кажется, соответствует ситуации асинхронного сервлета 3.0 / кометы, но все, что мне нужно сделать, это вернуть код ответа 200 (или другой) после принятия входящих параметров.
есть ли способ для HttpServlet завершить рукопожатие http-запроса / ответа и все же продолжить обработку?
что-то вроде...
doPost( req, response ) {
// verify input params...
response.setStatus( SC_OK );
response.close();
// execute long query
}
EDIT: глядя на javax.пакет сервлетов-правильная формулировка моего вопроса
Как я могу совершить ответ?
как в сервлет.isCommitted ()
4 ответов
вот как я справился с этой ситуацией:
- когда приложение запускается, создайте
ExecutorService
СExecutors.newFixedThreadPool(numThreads)
(есть и другие типы исполнителей, но я предлагаю начать с этого) - на
doPost()
создайте экземплярRunnable
, который будет выполнять нужную обработку - ваша задача - и представить его вExecutorService
вот так:executor.execute(task)
- наконец, вы должны вернуть статус HTTP
202 Accepted
и, если возможно,Location
заголовок, указывающий, где клиент сможет проверить состояние обработки.
Я очень рекомендую вам прочитать параллелизм Java на практике, это фантастическая и очень практичные книги.
о возможности для вашего сервлета принять запрос на обработку в фоновом режиме, для сервлета передать обработку в отдельный поток, который затем выполняется в фоновом режиме.
используя Spring, вы можете вызвать отдельный поток, используя a TaskExecutor. Преимущество использования spring над стандартным JDK 5 java.util.concurrent.Executor
Если вы находитесь на серверах приложений, которые должны использовать управляемые потоки (IBM websphere или Oracle weblogic), вы можете использовать WorkManagerTaskExecutor
чтобы зацепить менеджеров CommonJ work.
Другой альтернативой было бы переместить логику длинного запроса в управляемый сообщением боб или управляемый сообщением POJO (Весна JMS может помочь здесь), и пусть сервлет просто опубликует сообщение в очереди JMS. Это будет иметь то преимущество, что если нагрузка на ваш веб-контейнер станет слишком большой из-за вашего длительного запроса, вы можете легко переместить MDB в другую (выделенную) систему.
вы можете продолжить обработку в отдельном потоке.
ответ будет отправлен, как только вы вернетесь из doPost()
метод.
этот пример может помочь
void doPost(){
// do something
final ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
@Override
public void run() {
// processing after response
}
});}