3. Noções básicas de desenvolvimento web em Java
Vamos agora discutir o desenvolvimento de aplicações web dinâmicas, ou seja, aplicações nas quais as páginas HTML enviadas ao utilizador são geradas por programas.
3.1. Criação de um projeto Web no Eclipse
Iremos desenvolver a nossa primeira aplicação web utilizando o Eclipse/Tomcat. Seguiremos um processo semelhante ao utilizado para criar uma aplicação web sem o Eclipse. Com o Eclipse em execução, criamos um novo projeto:

que definimos como um projeto web dinâmico:

Na primeira página do assistente de criação, especificamos o nome do projeto [1] e a sua localização [2]:

Na segunda página do assistente, aceitamos os valores predefinidos:

A última página do assistente solicita que definamos o contexto da aplicação [3]:

Assim que o assistente for confirmado clicando em [Concluir], o Eclipse liga-se ao site [http://java.sun.com] para recuperar determinados documentos que pretende armazenar em cache, a fim de evitar tráfego de rede desnecessário. Em seguida, é solicitado um contrato de licença:

Aceitamo-lo. O Eclipse cria o projeto web. Para o apresentar, utiliza um ambiente, denominado perspetiva, que é diferente do utilizado num projeto Java tradicional:

A perspetiva associada a um projeto web é a perspetiva J2EE. Aceitamo-la para ver... O resultado é o seguinte:

A perspetiva J2EE é, na verdade, desnecessariamente complexa para projetos web simples. Neste caso, a perspetiva Java é suficiente. Para aceder a ela, usamos a opção [Janela -> Abrir perspetiva -> Java]:

src: conterá o código Java para as classes da aplicação, bem como os ficheiros que devem estar no classpath da aplicação.
build/classes (não mostrado): conterá os ficheiros .class das classes compiladas, bem como uma cópia de todos os ficheiros que não sejam .java localizados em src. Uma aplicação web utiliza frequentemente os chamados ficheiros de «recursos» que devem estar no classpath da aplicação, ou seja, o conjunto de diretórios que a JVM pesquisa quando a aplicação faz referência a uma classe, seja durante a compilação ou em tempo de execução. O Eclipse garante que o diretório build/classes faz parte do classpath da Web. Os ficheiros de «recursos» são colocados na pasta src, sabendo que o Eclipse os copiará automaticamente para build/classes.
WebContent: conterá os recursos da aplicação web que não precisam de estar no Classpath da aplicação.
WEB-INF/lib: contém os ficheiros .jar necessários à aplicação web.
Vamos examinar o conteúdo do ficheiro [WEB-INF/web.xml] que configura a aplicação [person]:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name> personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Já nos deparámos com este tipo de configuração quando estudámos a criação de páginas de boas-vindas na Secção 2.3.4. Este ficheiro limita-se a definir uma série de páginas de boas-vindas. Mantemos apenas a primeira. O ficheiro [web.xml] fica com o seguinte aspeto:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
O conteúdo do ficheiro XML acima deve estar em conformidade com as regras de sintaxe definidas no ficheiro especificado pelo atributo [xsi:schemaLocation] da tag de abertura <web-app>. Esse ficheiro encontra-se em [http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd]. Este é um ficheiro XML que pode ser acedido diretamente através de um navegador da Web. Se o navegador for suficientemente recente, será capaz de apresentar um ficheiro XML:

O Eclipse tentará validar o documento XML utilizando o ficheiro .xsd especificado no atributo [xsi:schemaLocation] da tag de abertura <web-app>. Para tal, irá efetuar um pedido de rede. Se o seu computador estiver numa rede privada, deve indicar ao Eclipse qual a máquina a utilizar para sair da rede privada, conhecida como proxy HTTP. Isto é feito através da opção [Janela -> Preferências -> Internet]:

Marque a caixa (1) se estiver numa rede privada. Em (2), introduza o nome da máquina que hospeda o proxy HTTP e, em (3), a sua porta de escuta. Por fim, em (4), especifique as máquinas que devem ignorar o proxy — máquinas que se encontram na mesma rede privada que a máquina em que está a trabalhar.
Vamos agora criar o ficheiro [index.html] para a página inicial.
3.2. Criação de uma página inicial
Clique com o botão direito do rato na pasta [WebContent] e selecione [Novo -> Outro]:

Selecione o tipo [HTML] e clique em [Seguinte] ->

Acima, selecione a pasta pai [WebContent] em (1) ou (2) e, em seguida, especifique o nome do ficheiro a criar em (3). Depois de fazer isto, avance para a página seguinte do assistente:

Com (1), podemos gerar um ficheiro HTML pré-preenchido com (2). Se desmarcarmos (1), geramos um ficheiro HTML vazio. Deixamos (1) marcado para beneficiar de um modelo de código. Concluímos o assistente clicando em [Concluir]. O ficheiro [index.html] é então criado:

com o seguinte conteúdo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
Modificamos este ficheiro da seguinte forma:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Application personne</title>
</head>
<body>
Application personne active...
<br>
<br>
Vous êtes sur la page d'accueil
</body>
</html>
3.3. Testar a página inicial
Se não estiver presente, exiba a vista [Servidores] utilizando a opção [Janela -> Mostrar Vista -> Outros -> Servidores] e, em seguida, clique com o botão direito do rato no servidor Tomcat 5.5:

A opção [Adicionar e Remover Objetos] acima permite-lhe adicionar ou remover aplicações web do servidor Tomcat:

Os projetos web reconhecidos pelo Eclipse estão listados em (1). Pode registá-los no servidor Tomcat utilizando (2). As aplicações web registadas no servidor Tomcat aparecem em (4). Pode cancelar o registo utilizando (3). Vamos registar o projeto [person]:

e, em seguida, conclua o assistente de registo clicando em [Concluir]. A vista [Servidores] mostra que o projeto [person] foi registado no Tomcat:

Agora, vamos iniciar o servidor Tomcat:
![]() | ![]() |
Abra o navegador da Web:

depois introduza o URL [http://localhost:8080/personne]. Este URL é a raiz da aplicação web. Não é solicitado nenhum documento. Neste caso, é apresentada a página inicial da aplicação. Se esta não existir, é apresentada uma mensagem de erro. Aqui, a página inicial existe. Trata-se do ficheiro [index.html] que criámos anteriormente. O resultado é o seguinte:

Corresponde ao esperado. Agora, vamos utilizar um navegador fora do Eclipse e solicitar a mesma URL:

A aplicação web [person] é, portanto, também acessível fora do Eclipse.
3.4. Criação de um formulário HTML
Vamos agora criar um documento HTML estático [form.html] na pasta [person]:

Para o criar, siga o procedimento descrito na secção 3.2, página 33. O seu conteúdo será o seguinte:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Retablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
O código HTML acima corresponde ao formulário abaixo:

Tipo HTML | nome | Código HTML | função | |
<input type="text"> | txtName | linha 14 | introduza o nome | |
<input type="text"> | txtIdade | linha 18 | entrada de idade | |
<input type="submit"> | linha 23 | Envie os valores introduzidos para o servidor na URL /person1/main | ||
<input type="reset"> | linha 24 | para restaurar a página ao estado em que foi inicialmente recebida pelo navegador | ||
<input type="button"> | linha 25 | para limpar o conteúdo dos campos de entrada [1] e [2] |
Vamos guardar o documento na pasta <person>/WebContent. Inicie o Tomcat, se necessário. Utilizando um navegador, aceda ao URL http://localhost:8080/personne/formulaire.html:

A arquitetura cliente/servidor desta aplicação básica é a seguinte:

O servidor web situa-se entre o utilizador e a aplicação web e não foi representado aqui. [formulaire.html] é um documento estático que devolve o mesmo conteúdo para cada pedido do cliente. A programação web tem como objetivo gerar conteúdo adaptado ao pedido do cliente. Este conteúdo é então gerado programaticamente. Uma solução consiste em utilizar uma JSP (Java Server Page) em vez do ficheiro HTML estático. É isso que vamos agora examinar.
3.5. Criação de uma página JSP
Leituras [ref1]: Capítulo 1, Capítulo 2: 2.2, 2.2.1, 2.2.2, 2.2.3, 2.2.4
A arquitetura cliente/servidor anterior é transformada da seguinte forma:

Uma página JSP é um tipo de página HTML parametrizada. Certos elementos da página só recebem os seus valores em tempo de execução. Estes valores são calculados pelo programa. Temos, portanto, uma página dinâmica: pedidos sucessivos à página podem gerar respostas diferentes. Aqui, referimo-nos à página HTML apresentada pelo navegador do cliente como a resposta. Em última análise, o navegador recebe sempre um documento HTML. Este documento HTML é gerado pelo servidor web a partir da página JSP, que serve de modelo. Os seus elementos dinâmicos são substituídos pelos seus valores reais no momento em que o documento HTML é gerado.
Para criar uma página JSP, clique com o botão direito do rato na pasta [WebContent] e selecione a opção [Novo -> Outro]:

Selecionamos o tipo [JSP] e clicamos em [Next] ->

Acima, selecionamos a pasta pai [WebContent] em (1) ou (2) e, em seguida, especificamos em (3) o nome do ficheiro a ser criado. Feito isto, passamos para a página seguinte do assistente:

Com (1), podemos gerar um ficheiro JSP pré-preenchido com (2). Se desmarcarmos (1), geramos um ficheiro JSP vazio. Deixamos (1) marcado para beneficiar de um modelo de código. Concluímos o assistente clicando em [Concluir]. O ficheiro [formulaire.jsp] é então criado:

com o seguinte conteúdo:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
A linha 1 indica que estamos a lidar com uma página JSP. Transformamos o texto acima da seguinte forma:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// on récupère les paramètres
String nom=request.getParameter("txtNom");
if(nom==null) nom="inconnu";
String age=request.getParameter("txtAge");
if(age==null) age="xxx";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
O documento inicialmente estático tornou-se agora dinâmico através da introdução de código Java. Para este tipo de documento, procederemos sempre da seguinte forma:
- Colocamos o código Java no início do documento para recuperar os parâmetros necessários para a sua apresentação. Estes encontram-se frequentemente no objeto request. Este objeto representa o pedido do cliente. Pode ter passado por vários servlets e páginas JSP que o tenham enriquecido. Aqui, provém diretamente do navegador.
- Segue-se o código HTML. Normalmente, este irá simplesmente apresentar variáveis previamente calculadas no código Java utilizando as tags <%= variável %>. Note-se aqui que o sinal = está mesmo ao lado do sinal %. Esta é uma causa comum de erros.
O que faz o documento dinâmico anterior?
- Linhas 6–9: Recupera dois parâmetros da solicitação, denominados [txtNom] e [txtAge], e atribui os seus valores às variáveis [nom] (linha 6) e [age] (linha 8). Se não encontrar os parâmetros, atribui valores padrão às variáveis associadas.
- Exibe os valores das duas variáveis [name, age] no seguinte código HTML (linhas 25 e 29).
Vamos realizar um teste inicial. Inicie o Tomcat, se necessário, e utilize um navegador para aceder ao URL http://localhost:8080/personne/formulaire.jsp:

O documento form.jsp foi chamado sem passar quaisquer parâmetros. Por conseguinte, foram apresentados os valores predefinidos. Agora, vamos solicitar o URL http://localhost:8080/personne/formulaire.jsp?txtNom=martin&txtAge=14:

Desta vez, passámos os parâmetros txtNom e txtAge para a página form.jsp, que é o que ela espera. Em seguida, a página exibiu-os. Sabemos que existem dois métodos para passar parâmetros para uma página web: GET e POST. Em ambos os casos, os parâmetros passados são armazenados no objeto request predefinido. Aqui, foram passados utilizando o método GET.
3.6. Criação de um servlet
Leituras [ref1]: Capítulo 1, Capítulo 2: 2.1, 2.1.1, 2.1.2, 2.3.1
Na versão anterior, o pedido do cliente era tratado por uma página JSP. Aquando da primeira chamada a esta página, o servidor web — neste caso, o Tomcat — cria uma classe Java a partir da página e compila-a. É o resultado desta compilação que, em última análise, processa o pedido do cliente. A classe gerada a partir da página JSP é um servlet porque implementa a interface [javax.Servlet]:

A solicitação do cliente pode ser tratada por qualquer classe que implemente esta interface. Vamos agora criar uma classe desse tipo: ServletFormulaire. A arquitetura cliente/servidor anterior é transformada da seguinte forma:

Com a arquitetura baseada em JSP, o documento HTML enviado ao cliente era gerado pelo servidor web a partir da página JSP que servia de modelo. Aqui, o documento HTML enviado ao cliente será inteiramente gerado pelo servlet.
3.6.1. Criação do servlet
No Eclipse, clique com o botão direito do rato na pasta [src] e selecione a opção para criar uma classe:

em seguida, defina as características da classe a ser criada:

Em (1), introduza o nome de um pacote; em (2), introduza o nome da classe a criar. Esta classe deve herdar da classe especificada em (3). Não é necessário digitar manualmente o nome completo da classe. O botão (4) permite aceder às classes que se encontram atualmente no classpath da aplicação web:

Em (1), digite o nome da classe que está a procurar. Em (2), verá as classes no Classpath cujos nomes contêm a sequência digitada em (1).
Após confirmar o assistente de criação, o projeto web [person] é modificado da seguinte forma:

A classe [ServletFormulaire] foi criada com um esqueleto de código:

A captura de ecrã acima mostra que o Eclipse apresenta um [aviso] na linha que declara a classe. Clique no ícone (lâmpada) que indica este [aviso]:

Depois de clicar em (1), são sugeridas soluções para remover o [aviso] em (2). Ao selecionar uma delas, a alteração de código resultante dessa escolha aparece em (3).
O Java 1.5 introduziu alterações na linguagem Java, e o que era correto numa versão anterior pode agora desencadear [avisos]. Estes não indicam erros que impeçam a compilação da classe. Estão lá para chamar a atenção do programador para áreas do código que poderiam ser melhoradas. O atual [aviso] indica que uma classe deve ter um número de versão. Isto é utilizado para a serialização/desserialização de objetos, ou seja, quando um objeto Java .class na memória deve ser convertido numa sequência de bits enviados sequencialmente num fluxo de escrita, ou o inverso, quando um objeto Java .class na memória deve ser criado a partir de uma sequência de bits lidos sequencialmente num fluxo de leitura. Tudo isto está muito longe das nossas preocupações atuais. Por isso, vamos pedir ao compilador para ignorar este aviso, escolhendo a opção [Add @SuppressWarnings ...]. O código passa então a ser o seguinte:

Não há mais [avisos]. A linha adicionada é chamada de «anotação», um conceito introduzido no Java 1.5. Vamos completar este código mais tarde.
3.6.2. Classpath de um projeto Eclipse
O classpath de uma aplicação Java é o conjunto de pastas e ficheiros .jar pesquisados quando o compilador a compila ou quando a JVM a executa. Estes dois classpaths não são necessariamente idênticos, uma vez que algumas classes só são necessárias em tempo de execução e não durante a compilação. Tanto o compilador Java como a JVM têm um argumento que permite especificar o classpath da aplicação a ser compilada ou executada. De uma forma mais ou menos transparente para o utilizador, o Eclipse trata da construção e da passagem deste argumento para a JVM.
Como pode determinar os elementos do classpath de um projeto do Eclipse? Utilizando a opção [<projeto> / Build Path / Configure Build Path]:

Isto abre o seguinte assistente de configuração:

O separador (1) [Libraries] permite definir a lista de ficheiros .jar que fazem parte do classpath da aplicação. Estes são, portanto, pesquisados pela JVM quando a aplicação solicita uma classe. Os botões [2] e [3] permitem-lhe adicionar arquivos ao Classpath. O botão [2] permite-lhe selecionar arquivos localizados nas pastas de projetos geridos pelo Eclipse, enquanto o botão [3] permite-lhe selecionar qualquer arquivo do sistema de ficheiros do computador.
Acima, aparecem três bibliotecas:
- [JRE System Library]: a biblioteca base para projetos Java do Eclipse:

- [Runtime Tomcat v5.5]: uma biblioteca fornecida pelo servidor Tomcat. Contém as classes necessárias para o desenvolvimento web. Esta biblioteca está incluída em qualquer projeto web do Eclipse que tenha sido associado ao servidor Tomcat.

É o arquivo [servlet-api.jar] que contém a classe [javax.servlet.http.HttpServlet], a classe pai da classe [ServletFormulaire] que estamos a criar atualmente. É porque este arquivo está no Classpath da aplicação que ele pode ser sugerido como classe pai no assistente mostrado abaixo.

Se não fosse esse o caso, não teria aparecido nas sugestões em [2]. Portanto, se neste assistente pretender referenciar uma classe pai e esta não for sugerida, significa que ou escreveu mal o nome da classe, ou que o arquivo que a contém não se encontra no Classpath da aplicação.
- [Web App Libraries] contém os arquivos localizados na pasta [WEB-INF/lib] do projeto. Aqui, está vazio:

Os arquivos no classpath do projeto Eclipse são visíveis no explorador de projetos. Por exemplo, para o projeto web [person]:

O explorador de projetos dá-nos acesso ao conteúdo destes arquivos:

Como mostrado acima, podemos ver que o arquivo [servlet-api.jar] contém a classe [javax.servlet.http.HttpServlet].
3.6.3. Configuração do Servlet
Leituras [ref1]: Capítulo 2: 2.3, 2.3.1, 2.3.2, 2.3.3, 2.3.4
O ficheiro [WEB-INF/web.xml] é utilizado para configurar a aplicação web:

Para o projeto [person], este ficheiro tem atualmente o seguinte aspeto (ver página 32):
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Isto apenas indica a existência de um ficheiro de boas-vindas (linha 8). Modificamo-lo para declarar:
- a existência do servlet [ServletFormulaire]
- as URLs tratadas por este servlet
- os parâmetros de inicialização do servlet
O ficheiro web.xml da nossa aplicação ficará da seguinte forma:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Os pontos principais deste ficheiro de configuração são os seguintes:
- As linhas 7–24 estão relacionadas com a presença do servlet [ServletFormulaire]
- Linhas 7–20: Um servlet é configurado entre as tags <servlet> e </servlet>. Uma aplicação pode conter vários servlets e, por conseguinte, várias secções de configuração <servlet>...</servlet>.
- Linha 8: A tag <servlet-name> atribui um nome ao servlet — pode ser qualquer nome
- Linhas 9–11: A tag <servlet-class> especifica o nome completo da classe do servlet. O Tomcat irá procurar esta classe no classpath do projeto web [personne]. Encontrá-la-á em [build/classes]:
![]()
- Linhas 12–15: A tag <init-param> é utilizada para passar parâmetros de configuração para o servlet. Estes são geralmente lidos no método init do servlet, uma vez que os seus parâmetros de configuração devem ser conhecidos assim que este é carregado pela primeira vez.
- Linhas 13–14: A tag <param-name> define o nome do parâmetro e <param-value> define o seu valor.
- As linhas 12–15 definem um parâmetro [defaultName, "unknown"], e as linhas 16–19 definem um parâmetro [defaultAge, "XXX"]
- Linhas 21–24: A tag <servlet-mapping> é utilizada para associar um servlet (servlet-name) a um padrão de URL (url-pattern). Aqui, o padrão é simples. Especifica que sempre que um URL assumir a forma /formulaire, o servlet formulairepersonne deve ser utilizado, ou seja, a classe [istia.st.servlets.ServletFormulaire] (linhas 8–11). Por conseguinte, apenas um URL é aceite pelo servlet [formulairepersonne].
3.6.4. O código para o servlet [ServletFormulaire]
O servlet [ServletFormulaire] terá o seguinte código:
Basta ler o servlet para perceber que é muito mais complexo do que a página JSP correspondente. Esta é uma regra geral: um servlet não é adequado para gerar código HTML. As páginas JSP foram concebidas para esse fim. Teremos oportunidade de voltar a este assunto mais tarde. Vamos esclarecer alguns pontos importantes sobre o servlet acima:
- Quando um servlet é chamado pela primeira vez, o seu método init (linha 20) é chamado. Esta é a única vez que é chamado.
- Se o servlet foi chamado através do método HTTP GET, o método doGet (linha 32) é chamado para processar o pedido do cliente.
- Se o servlet foi chamado através do método HTTP POST, o método doPost (linha 82) é chamado para processar o pedido do cliente.
O método init é utilizado aqui para recuperar os valores dos parâmetros de inicialização denominados «defaultName» e «defaultAge» do ficheiro [web.xml]. O método init, executado quando o servlet é carregado pela primeira vez, é o local adequado para recuperar o conteúdo do ficheiro [web.xml].
- Linha 22: A configuração [config] do projeto web é recuperada. Este objeto reflete o conteúdo do ficheiro [WEB-INF/web.xml] da aplicação.
- Linha 23: Nesta configuração, recuperamos o valor String do parâmetro denominado "defaultName". Este parâmetro conterá o nome de uma pessoa. Se não existir, o valor será nulo.
- Linhas 24–25: Se o parâmetro denominado "defaultName" não existir, é atribuído um valor padrão à variável [defaultName].
- Linhas 26–29: Fazemos o mesmo para o parâmetro denominado "defaultAge".
O método doPost remete para o método doGet. Isto significa que o cliente pode enviar os seus parâmetros utilizando uma solicitação POST ou GET.
O método doGet:
- Linha 32: O método recebe dois parâmetros, `request` e `response`. `request` é um objeto que representa toda a solicitação do cliente. É do tipo `HttpServletRequest`, que é uma interface. `response` é do tipo `HttpServletResponse`, que também é uma interface. O objeto `response` é usado para enviar uma resposta ao cliente.
- request.getParameter("param") é utilizado para recuperar o valor do parâmetro denominado "param" da solicitação do cliente. Na linha 36, recuperamos o valor do parâmetro "txtNom"; na linha 40, o do parâmetro "txtAge". Se estes parâmetros não estiverem presentes na solicitação, o valor do parâmetro é definido como nulo.
- Linhas 37–39: Se o parâmetro "txtNom" não estiver na solicitação, à variável "nom" é atribuído o nome padrão "defaultNom", inicializado no método init. O mesmo é feito nas linhas 41–43 para a idade.
- Linha 45: response.setContentType(String) é utilizado para definir o valor do cabeçalho HTTP Content-Type. Este cabeçalho indica ao cliente a natureza do documento que irá receber. O tipo text/html indica um documento HTML.
- Linha 46: response.getWriter() é utilizado para obter um fluxo de escrita para o cliente
- Linhas 47–78: O documento HTML a ser enviado ao cliente é gravado no fluxo de escrita obtido na linha 46.
A compilação deste servlet irá gerar um ficheiro .class na pasta [build/classes] do projeto [person]:

Recomenda-se aos leitores que consultem a documentação Java sobre servlets. O Tomcat pode ser utilizado para este fim. Na página inicial do Tomcat 5, existe um link [Documentação]:

Este link leva a uma página que o leitor é encorajado a explorar. O link para a documentação do servlet é o seguinte:

3.6.5. Testar o servlet
Estamos prontos para executar um teste. Inicie o servidor Tomcat, se necessário.

Em seguida, utilizando um navegador, solicite a URL [http://localhost:8080/personne/formulaire]. Aqui, estamos a solicitar a URL [/form] a partir do contexto [/person]. O ficheiro [web.xml] para este contexto especifica que a URL [/form] é tratada pelo servlet denominado [formperson]. No mesmo ficheiro, está especificado que este servlet é a classe [istia.st.servlets.ServletFormulaire]. O Tomcat irá, portanto, confiar a esta classe o processamento do pedido do cliente. Se a classe ainda não tiver sido carregada, será carregada. Permanecerá então na memória para pedidos futuros.
Obtemos o seguinte resultado utilizando o navegador integrado do Eclipse:

Obtemos os valores predefinidos para nome e idade, conforme especificado no ficheiro [web.xml]. Agora, vamos solicitar a URL [http://localhost:8080/personne/formulaire?txtNom=tintin&txtAge=30]:

Desta vez, obtemos os parâmetros passados na solicitação. O leitor é convidado a rever o código do servlet [ServletFormulaire] caso não compreenda estes dois resultados.
3.6.6. Recarregamento automático do contexto da aplicação web
Vamos iniciar o Tomcat:

e, em seguida, modifique o código do servlet da seguinte forma:
- A linha 8 foi modificada
Vamos guardar a nova classe. Esta gravação irá desencadear uma recompilação automática da classe [ServletFormulaire] pelo Eclipse, que o Tomcat irá detetar. Em seguida, irá recarregar o contexto da aplicação web [personne] para refletir as alterações. Isto aparece nos registos da vista [console]:

Vamos solicitar a URL [http://localhost:8080/personne/formulaire] sem reiniciar o Tomcat:

A alteração foi aplicada com sucesso.
Agora, vamos modificar o ficheiro [web.xml] da seguinte forma:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<servlet>
<servlet-name>formulairepersonne</servlet-name>
...
<init-param>
<param-name>defaultNom</param-name>
<param-value>INCONNU</param-value>
</init-param>
...
</servlet>
...
</web-app>
- A linha 12 foi modificada
Agora que isto está feito, vamos guardar o novo ficheiro [web.xml]. Na vista [console], nenhum registo indica que o contexto da aplicação foi recarregado. Vamos solicitar o URL [http://localhost:8080/personne/formulaire] sem reiniciar o Tomcat:

A alteração não foi aplicada. Vamos reiniciar o Tomcat [clique com o botão direito do rato no servidor -> Reiniciar -> Iniciar]:

e, em seguida, solicitemos a URL [http://localhost:8080/personne/formulaire] novamente:

Desta vez, a alteração feita no [web.xml] está visível.
Uma alteração no [web.xml] não desencadeia automaticamente uma recarga da aplicação que incorpore o novo ficheiro de configuração. Para forçar a recarga da aplicação web, pode reiniciar o Tomcat como fizemos, mas este é um processo bastante lento. É preferível utilizar a ferramenta [manager] para administrar aplicações implementadas no Tomcat. Para que isto funcione, o Tomcat deve ter sido configurado no Eclipse conforme mostrado na Secção 2.5.
Primeiro, utilizando o navegador interno do Eclipse, introduza o URL [http://localhost:8080] e, em seguida, siga a ligação [Tomcat Manager], conforme explicado no final da Secção 2.5:

Vamos abrir um segundo navegador [clique com o botão direito do rato no navegador -> Novo Editor]:
![]() | ![]() |
Neste segundo navegador, introduza o URL [http://localhost:8080/formulaire]:

Modifique o ficheiro [web.xml] da seguinte forma e, em seguida, guarde-o:
<!-- ServletFormulaire -->
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>YYY</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
Em seguida, solicite novamente a URL [http://localhost:8080/formulaire]. Podemos ver que a alteração não foi aplicada. Agora, vá para o primeiro navegador e atualize a aplicação [person]:

Em seguida, solicite a URL [http://localhost:8080/formulaire] novamente utilizando o segundo navegador:

A alteração ao [web.xml] foi aplicada. Na prática, é útil ter um navegador aberto na aplicação [manager] do Tomcat para lidar com este tipo de situação.
3.7. Interação entre Servlets e Páginas JSP
Leituras [ref1]: Capítulo 2: 2.3.7
Voltemos às duas arquiteturas que analisámos:

Nenhuma destas duas arquiteturas é satisfatória. Ambas têm a desvantagem de misturar duas tecnologias: a programação Java, que lida com a lógica da aplicação web, e a codificação HTML, que lida com a apresentação da informação num navegador.
- A solução baseada em JSP [1] tem a desvantagem de misturar código HTML e código Java na mesma página. Não vimos isso no exemplo que abordámos, que era básico. Mas se [formulaire.jsp] tivesse de validar os parâmetros [txtNom, txtAge] no pedido do cliente, teríamos sido obrigados a colocar código Java na página. Isto torna-se rapidamente incontrolável.
- A solução [2], baseada num servlet, apresenta o mesmo problema. Embora haja apenas código Java na classe, esta deve gerar um documento HTML. Mais uma vez, a menos que o documento HTML seja básico, a sua geração torna-se complicada e quase impossível de manter.
Iremos evitar a mistura de tecnologias Java e HTML adotando a seguinte arquitetura:

- O utilizador envia o seu pedido ao servlet. O servlet processa-o e constrói os valores para os parâmetros dinâmicos da página JSP [form.jsp], que serão utilizados para gerar a resposta HTML para o cliente. Estes valores formam o que é conhecido como o modelo da página JSP.
- Assim que o seu trabalho estiver concluído, o servlet solicitará à página JSP [form.jsp] que gere a resposta HTML para o cliente. Ao mesmo tempo, fornecerá à página JSP os elementos de que esta necessita para gerar essa resposta — os elementos que compõem o modelo da página.
Vamos agora explorar esta nova arquitetura.
3.7.1. O servlet [ServletFormulaire2]
Na arquitetura acima, o servlet será denominado [ServletFormulaire2]. Será criado no mesmo projeto [personne] de antes, juntamente com todos os futuros servlets:

O [ServletFormulaire2] é criado inicialmente através da cópia e colagem do [ServletFormulaire] no Eclipse:
- selecione [ServletFormulaire.java] -> clique com o botão direito do rato -> Copiar
- Selecione [istia.st.servlets.personne] -> clique com o botão direito do rato -> Colar -> renomeie para [ServletFormulaire2.java]
Em seguida, modificamos o código de [ServletFormulaire2] da seguinte forma:
Apenas a parte que gera a resposta HTTP foi alterada (linhas 44–46):
- Linha 46: A página JSP `formulaire2.jsp` é responsável por gerar a resposta. Esta página, que ainda não abordámos, irá apresentar os parâmetros recuperados do pedido do cliente: um nome (linhas 35–38) e uma idade (linhas 39–42).
- Estes dois valores são colocados nos atributos da solicitação, associados a chaves. Os atributos da solicitação são geridos como um dicionário.
- Linha 44: O nome é colocado na solicitação associado à chave "name"
- Linha 45: A idade é colocada na solicitação associada à chave "age"
- Linha 46: Solicita a exibição da página JSP [formulaire2.jsp]. O seguinte é passado como parâmetro para ela:
- a solicitação do cliente, que permite à página JSP aceder aos seus atributos que acabaram de ser inicializados pelo servlet
- a resposta [response], que permitirá à página JSP gerar a resposta HTTP para o cliente
Depois de escrita a classe [ServletFormulaire2], o seu código compilado aparece em [build/classes]:

3.7.2. A página JSP [formulaire2.jsp]
A página JSP formulaire2.jsp é criada através da cópia e colagem da página [formulaire.jsp]

e, em seguida, é modificada da seguinte forma:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// on récupère les valeurs nécessaire à l'affichage
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Personne - formulaire2</title>
</head>
<body>
<center>
<h2>Personne - formulaire2</h2>
<hr>
<form action="" method="post">
<table>
<tr>
<td>Nom</td>
<td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
</tr>
<tr>
<td>Age</td>
<td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
</tr>
</table>
<table>
<tr>
<td><input type="submit" value="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
</form>
</center>
</body>
</html>
Apenas as linhas 4–8 foram alteradas em comparação com [formulaire.jsp]:
- linha 6: recupera o valor do atributo denominado «name» no [request], um atributo criado pelo servlet [ServletFormulaire2].
- linha 7: faz o mesmo para o atributo «age»
3.7.3. Configuração da aplicação
O ficheiro de configuração [web.xml] é modificado da seguinte forma:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>personne</display-name>
<!-- ServletFormulaire -->
<servlet>
<servlet-name>formulairepersonne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXXX</param-value>
</init-param>
</servlet>
<!-- ServletFormulaire 2-->
<servlet>
<servlet-name>formulairepersonne2</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletFormulaire2
</servlet-class>
<init-param>
<param-name>defaultNom</param-name>
<param-value>inconnu</param-value>
</init-param>
<init-param>
<param-name>defaultAge</param-name>
<param-value>XXX</param-value>
</init-param>
</servlet>
<!-- Mapping ServletFormulaire -->
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<!-- Mapping ServletFormulaire 2-->
<servlet-mapping>
<servlet-name>formulairepersonne2</servlet-name>
<url-pattern>/formulaire2</url-pattern>
</servlet-mapping>
<!-- welcome files -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Mantivemos o código existente e adicionámos:
- Linhas 22–36: uma secção <servlet> para definir o novo servlet ServletFormulaire2
- Linhas 42–46: uma secção <servlet-mapping> para associá-lo à URL /formulaire2
Inicie ou reinicie o servidor Tomcat, se necessário. Solicitamos a URL
http://localhost:8080/personne/formulaire2?txtNom=milou&txtAge=10:

Obtemos o mesmo resultado que antes, mas a estrutura da nossa aplicação está agora mais clara: um servlet que contém a lógica da aplicação e delega a tarefa de enviar a resposta ao cliente a uma página JSP. A partir de agora, procederemos sempre desta forma.



