Quando doPost é chamado? Antes ou depois do envio completo dos dados?

8 respostas
EderBaum

Estive pesquisando pela net e não achei quase nada falando sobre isto, mas minha duvida é relativamente simples.

Imagine que enviei um formulário via POST com apenas dois campos.
Titulo -> Um String de poucos Bytes
Conteudo -> Um String enorme, com talvez 2MB.

Minha duvida é quanto será a chamada do metodo doPost do Servlet.
A) Este método só é chamado quando o envio de tudo estiver em 100% com o Stream completinho no servidor?
B) Assim que a requisição “toca” o servlet, o método doPost já é chamado, mesmo com os dados parcialmente enviados, cabendo a este método ler o Stream de dados.

Pelo que trabalhei com Upload de arquivos, a resposta lógica seria a B.
Tal pergunta é extremamente pertinente, pois através desta resposta saberei onde melhor colocar uma abertura de conexão com o banco de dados por exemplo (Antes ou depois de ler todos os dados).

8 Respostas

P

Ola,

Correto. Se ja existir uma instancia do Servlet, o container fornece um Thread que executa o metodo service do Servlet, que por
sua vez, no caso, invoca o metodo doPost. No metodo doPost voce obtem um InputStream do HttpServletRequest para ler
os bytes enviados. Com relacao a conexao com a base de dados, lembre-se que de qualquer forma nao eh interessante voce obte-la
no contexto de um Servlet, seja localmente ou como variavel de instancia. Localmente pois cada request ira implicar numa nova conexao
sendo criada e isso tem um grande impacto em performance e escalabilidade nao somente da sua aplicacao mas tambem do SGBD. Como
variavel de instancia porque uma unica conexao sera compartilhada por todos os Threads e isso pode gerar problemas de concorrencia,
e com isso afetar a performance e disponibilidade de sua aplicacao. Sugestao: Implemente uma arquitetura 3-tier:
Presentation Tier (JSP/Servlet) => Business Tier (Logica da aplicacao) => Integration Tier (Logica de acesso aos dados / persistencia).
Na camada de integracao implemente um DAO que utilizada um connection pooling gerenciado pelo container. Com isso voce garante melhor
manutenabilidade, extensibilidade, disponibilidade, performance e escalabilidade para a sua aplicacao :slight_smile:

[ ]'s

lazaropj

schranko:
Ola,

Correto. Se ja existir uma instancia do Servlet, o container fornece um Thread que executa o metodo service do Servlet, que por
sua vez, no caso, invoca o metodo doPost. No metodo doPost voce obtem um InputStream do HttpServletRequest para ler
os bytes enviados. Com relacao a conexao com a base de dados, lembre-se que de qualquer forma nao eh interessante voce obte-la
no contexto de um Servlet, seja localmente ou como variavel de instancia. Localmente pois cada request ira implicar numa nova conexao
sendo criada e isso tem um grande impacto em performance e escalabilidade nao somente da sua aplicacao mas tambem do SGBD. Como
variavel de instancia porque uma unica conexao sera compartilhada por todos os Threads e isso pode gerar problemas de concorrencia,
e com isso afetar a performance e disponibilidade de sua aplicacao. Sugestao: Implemente uma arquitetura 3-tier:
Presentation Tier (JSP/Servlet) => Business Tier (Logica da aplicacao) => Integration Tier (Logica de acesso aos dados / persistencia).
Na camada de integracao implemente um DAO que utilizada um connection pooling gerenciado pelo container. Com isso voce garante melhor
manutenabilidade, extensibilidade, disponibilidade, performance e escalabilidade para a sua aplicacao :slight_smile:

[ ]'s

Cara, bela explicação.
Essa arquitetura na qual vc citou, a 3-tier, é diferente de MVC?

P

Cara, bela explicação.
Essa arquitetura na qual vc citou, a 3-tier, é diferente de MVC?

Obrigado!

Numa arquitetura 3-tier utilizando JEE o MVC eh implementado na Presentation Tier. Note que se voce definir
uma arquiterura Web-Centric (por exemplo: Browser <=> Web Container <=> Database), entao necessariamente
o Web Container ira conter a implementacao das 3 camadas, e portanto seus componentes (por exemplo: JSPs,
Controllers, JavaBeans, Facades, DAOs, etc) serao acessados localmente um pelo outro. Contudo, se voce definir
uma arquitetura EJB-Centric (por exemplo: Browser <=> Web Container <=> EJB Container <=> Database), entao o
MVC continua implementado na Presentation Tier (no Web Container) e voce deve implementar alguns presentation-to-business
patterns (por exemplo Business Delegate) para acessar a Business Logic Tier agora implementada em componetes remotos EJB
(Stateless/Statefull Session Beans, por exemplo).

[ ]'s

EderBaum

schranko:
Com relacao a conexao com a base de dados, lembre-se que de qualquer forma nao eh interessante voce obte-la
no contexto de um Servlet, seja localmente ou como variavel de instancia.

Na verdade só citei isso pq foi a primeira coisa que veio na cabeça. Uso Pool de Conexão, JPA, etc…
Mas acho interessante este detalhe da leitura dos dados pois um código assim:

OutputStream os = new FileOutputStream("C:\\Arquivo.txt"); String texto = request.getParameter("texto"); os.write(texto.getBytes());

É menos eficiente que este:

String texto = request.getParameter("texto"); OutputStream os = new FileOutputStream("C:\\Arquivo.txt"); os.write(texto.getBytes());

M

Ola, é impressão minha, ou vc simplesmente inverteu a linha 1 pela 2???

Hebert_Coelho

Pois é, não entendi o pq isso afetaria o desempenho.

EderBaum

Sim exatamente.
Apenas inverti as linhas.

Como você podem ler na discução acima imaginem que o parametro “texto” tem um tamnho de 10MB.
A leitura desta informação começará quando o primeiro byte deste parãmetro começar a ser enviado pelo navegador do cliente e só acabará quando tudo estiver no lado do servidor (Imagine isso numa conexão discada).

Enquanto isso o arquivo “C:\Arquivo.txt” fica “esperando” até o envio de dados estar completo.

O que não ocorre no segundo caso.

Hebert_Coelho

Caso queria otimizar o código, foi poderia fazer algo muito ninjitsu com multi-thread.

Poderia picar o arquivo em várias partes e subir todas de uma vez… :twisted:

Criado 14 de dezembro de 2010
Ultima resposta 16 de dez. de 2010
Respostas 8
Participantes 5