Eu tenho uma situação que parece se encheckboxr na situação do Async Servlet 3.0 / Comet, mas tudo que eu preciso fazer é retornar um código de resposta 200 (ou outro) depois de aceitar os parâmetros de input.
Existe uma maneira de um HttpServlet concluir o handshake de solicitação / resposta http e continuar processando?
Algo como…
doPost( req, response ) { // verify input params... response.setStatus( SC_OK ); response.close(); // execute long query }
EDIT: Olhando para o pacote javax.servlet – o fraseado apropriado para minha pergunta é
Como faço para confirmar uma resposta?
como em Servlet.isCommitted ()
Veja como lidamos com essa situação:
ExecutorService
com Executors.newFixedThreadPool(numThreads)
(existem outros tipos de executores, mas sugiro começar com este) doPost()
, crie uma instância de Runnable
que executará o processamento desejado – sua tarefa – e envie-o para o ExecutorService
forma: executor.execute(task)
202 Accepted
e, se possível, um header de Location
indicando onde um cliente poderá verificar o status do processamento. Eu recomendo que você leia Java Concurrency in Practice , é um livro fantástico e muito prático.
Na possibilidade de seu servlet aceitar uma solicitação para processamento em segundo plano, é para o servlet passar o processamento para um encadeamento separado que, em seguida, é executado em segundo plano.
Usando o Spring, você pode invocar um Thread separado usando o TaskExecutor . A vantagem de usar o Spring sobre o JDK 5 padrão java.util.concurrent.Executor
é que, se você estiver em servidores de aplicativos que precisam usar encadeamentos gerenciados (IBM websphere ou Oracle weblogic), será possível usar o WorkManagerTaskExecutor
para conectar-se ao trabalho do CommonJ gerentes.
Outra alternativa seria mover a longa lógica de consulta para um Message Driven Bean ou Message Directed POJO (o Spring JMS pode ajudar aqui) e permitir que o servlet simplesmente publique uma mensagem em uma fila do JMS. Isso teria a vantagem de que, se a carga em seu contêiner da Web se tornasse grande demais devido à sua longa consulta, você poderia facilmente mover o MDB para um sistema diferente (dedicado).
Você pode continuar processando em um thread separado.
A resposta é confirmada quando você retorna do método doPost()
.
Este exemplo pode ajudar
void doPost(){ // do something final ExecutorService executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable() { @Override public void run() { // processing after response } });}