Завершение 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 ответов


вот как я справился с этой ситуацией:

  1. когда приложение запускается, создайте ExecutorService С Executors.newFixedThreadPool(numThreads) (есть и другие типы исполнителей, но я предлагаю начать с этого)
  2. на doPost() создайте экземпляр Runnable, который будет выполнять нужную обработку - ваша задача - и представить его в ExecutorService вот так: executor.execute(task)
  3. наконец, вы должны вернуть статус 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
          }
      });}