Artigo Java Magazine 18 - Programando Servlets

Artigo publicado na Java Magazine edição 18.

Esse artigo faz parte da revista Java Magazine edição 18. Clique aqui para ler todos os artigos desta edição

Clique aqui para ler este artigo em PDF

Programando Servlets

Parte 1: Fundamentos e Técnicas Básicas

No primeiro artigo da série, apresentaremos os conceitos básicos como protocolo HTTP, API, ciclo de vida, cookies e sessões

A API de Servlets, criada em 1996 com o intuito de gerar dinamicamente código HTML, é um componente fundamental da plataforma J2EE. Com o passar do tempo, porém, outras tecnologias, como JSP e linguagens de template, mostraram-se mais apropriadas para a geração de HTML, e os servlets passaram a ser usados para tarefas de processamento de dados, como download e upload de arquivos e filtragem de requisições. Mas isso não significa que os servlets perderam importância. Muito pelo contrário. A API de Servlets é o alicerce de muitas outras tecnologias, como JSP, JSF, Portlets e Struts. A Tabela 1 lista as tecnologias J2EE relacionadas à camada web (web-tier) e suas especificações (JSRs).

Nesse artigo, vamos apresentar os conceitos básicos de servlets e uma introdução ao funcionamento de uma aplicação web. Este artigo complementa e se relaciona com a outra matéria de capa de edição, sobre JSP 2.0 e Tomcat 5, e em alguns pontos mostrará conceitos similares, mas sob a perspectiva unificadora dos servlets.

O protocolo HTTP

Antes de nos aprofundarmos na API de Servlets em si, é importante entender como funciona o protocolo HTTP, responsável pela comunicação, em nível de aplicação, entre o navegador e a aplicação web. Quando você digita uma URL no navegador, digamos, http://localhost:8080/jm18/alo?nomePessoa=Felipe, é feita uma requisição (request) ao servidor HTTP. Aqui localhost representa o seu próprio computador. O servidor então processa a requisição e envia uma resposta (response) ao navegador. A Figura 1 ilustra o processo.

Junto com a requisição, o navegador passa algumas informações para o servidor. No exemplo ilustrado, está sendo explicitamente passado um parâmetro nomePessoa, cujo valor é felipe. Implicitamente, são passadas informações sobre o navegador através de variáveis de header e, opcionalmente, cookies (veremos mais sobre estes adiante).

Como a requisição é enviada no formato texto, podemos verificar o que é enviado usando o nosso "pseudo servidor web" mostrado na Listagem 1. Acessando esse servidor, por exemplo, a partir de um navegador Mozilla rodando no Linux (e passando a URL http://localhost:8080/alo?nomePessoa=Felipe), temos:

 

> java jm18.pentefino.ServidorHTTP 8080

### Criando servidor na porta 8080

### Conexao estabelecida

### Recebendo dados:

GET /aloServlet?nomePessoa=Felipe HTTP/1.1

Host: localhost:2424

User-Agent: Mozilla/5.0

(X11; U; Linux i686; en-US; rv:1.6) Gecko/20040116

Accept: text/xml,application/xml,application/xhtml+xml,

text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,

image/gif;q=0.2,*/*;q=0.1

Accept-Language: en-us,en;q=0.5

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 300

Connection: keep-alive

 

### Dados ok

### Enviando dados:

### Dados ok

 

Nesta requisição, a primeira linha indica ao servidor o recurso que está sendo acessado (/aloServlet?nomePessoa=Felipe), além da versão do protocolo e o método usado – HTTP/1.1 e GET. As linhas seguintes são variáveis de cabeçalho (header), seguidas por uma linha em branco, que separa o cabeçalho do corpo da requisição.

 

Nota: O corpo de uma requisição HTTP só é usado em requisições do tipo POST; é no corpo que os bytes de um arquivo são transmitidos em um upload, por exemplo.

 

O servidor envia uma resposta, também em formato texto. A estrutura é similar à requisição: a primeira linha indica o código da resposta (veja a Tabela 2), sendo seguida por variáveis de cabeçalho, uma linha em branco e o corpo. O corpo contém os dados da resposta, como código HTML ou bytes de um arquivo, no caso de um download.

Usando o cliente da Listagem 2 em vez do navegador web, o comando a ser executado e a resposta para o exemplo anterior seria:

 

> java jm18.pentefino.ServidorHTTP 8080

### Criando servidor na porta 8080

### Conexao estabelecida

### Recebendo dados:

GET /aloServlet?nomePessoa=Felipe HTTP/1.1

 

### Dados ok

### Enviando dados:

### Dados ok

 

E no cliente:

 

> java jm18.pentefino.ClienteHTTP http://localhost:8080/aloServlet?nomePessoa=Felipe

### Tentando conexao com servidor localhost na porta 8080

### Conexao estabelecida. Enviando query /aloServlet?nomePessoa=Felipe

### Recebendo resposta

### Dados enviados pelo servidor:

Requisicao tratada com sucesso!

### Dados ok


Note que o cliente da Listagem 2 não envia nenhuma variável de cabeçalho. Por isso não seria um cliente válido para servidores reais, como mostra o seguinte exemplo:

 

> java jm18.pentefino.ClienteHTTP http://javamagazine.com.br:80

### Tentando conexao com servidor javamagazine.com.br na porta 80

### Conexao estabelecida. Enviando query ?null

### Recebendo resposta

### Dados enviados pelo servidor:

HTTP/1.1 400 Bad Request

Date: Tue, 07 Sep 2004 18:17:08 GMT

Server: Apache

Connection: close

Transfer-Encoding: chunked

Content-Type: text/html; charset=iso-8859-1

 

127

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

<HTML><HEAD>

<TITLE>400 Bad Request</TITLE>

</HEAD><BODY>

<H1>Bad Request</H1>

Your browser sent a request that this server could not understand.<P>

client sent HTTP/1.1 request without hostname (see RFC2616 section 14.23): /<P>

</BODY></HTML>

 

0

 

### Dados ok

 

Para finalizar, é importante lembrar que o protocolo HTTP é sem-estado (stateless). Ou seja, não existe uma conexão permanente entre o servidor e o navegador, e portanto o servidor não sabe se uma conexão seguinte está relacionada com a anterior. Para contornar essa restrição, foram criados os cookies. Cookies são informações armazenadas no computador do usuário que são opcionalmente enviadas em cada requisição pelo navegador, processados pelo servidor e recebidos de volta na resposta (veja a Figura 2).

Servlets e aplicações web

Na Figura 1, vimos que o navegador faz uma requisição que será processada de alguma maneira pelo servidor. A forma como esse processamento é feito depende do servidor e da URL. Por exemplo, um servidor web Apache pode ser configurado para servir páginas estáticas em HTML e páginas dinâmicas em PHP, e para repassar as requisições de JSPs a um servidor Tomcat rodando na mesma máquina. Como se vê, a API de Servlets é uma dentre várias tecnologias de processamento de requisições HTTP para geração de páginas dinâmicas.

Os servlets não ficam sozinhos. Eles são gerenciados por um Container Web, responsável pela criação e destruição dos servlets e pela delegação de requisições HTTP para os servlets existentes, além da criação de um pool de threads para o processamento das requisições (cada requisição é atendida em uma thread própria). A Figura 3 ilustra o relacionamento entre o servidor HTTP, o container web e os servlets.

Outro conceito importante é o de Aplicação Web (Web Application, ou abreviadamente webapp). Todo servlet está contido numa aplicação web, que pode conter ainda outros recursos como páginas JSP e arquivos estáticos (páginas HTML, imagens JPG e GIF etc.), além de um diretório especial chamado WEB-INF (cujo conteúdo não é exposto por uma URL e só pode ser acessado pelos servlets) – veja a Figura 4. Para ser instalada, uma aplicação web é tipicamente condensada em um arquivo WAR (Web ARchive). Esse formato condensado é mais comumente usado na aplicação final em produção, e o formato “expandido”, durante o desenvolvimento.

Um container pode gerenciar várias aplicações web, cada uma em seu Contexto. Um contexto é identificado por um "diretório" na URL. Por exemplo, a URL http://localhost:8080/jm18/alo refere-se ao recurso alo da aplicação web cujo contexto mapeia para o "diretório" jm18.

Um servlet também é responsável pelo tratamento de URLs da aplicação web. No exemplo anterior, poderíamos criar um servlet chamado " [...] continue lendo...

Artigos relacionados