3. Noções básicas de desenvolvimento web em Java
Passamos agora ao desenvolvimento de aplicações web dinâmicas, c.a.d, nas quais as páginas HTML enviadas ao utilizador são geradas por programas.
3.1. Criação de um projeto web no Eclipse
Vamos desenvolver uma primeira aplicação web com o Eclipse/Tomcat. Seguimos um procedimento semelhante ao utilizado para criar uma aplicação web sem o Eclipse. Com o Eclipse iniciado, 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-nos que definamos o contexto [3] da aplicação:

Assim que o assistente for validado por [Finish], o Eclipse liga-se ao site [http://java.sun.com] para recuperar determinados documentos que pretende armazenar em cache, a fim de evitar acessos desnecessários à rede. É então solicitada uma autorização de licença:

Aceita-se. O Eclipse cria o projeto web. Para o apresentar, utiliza um ambiente, denominado «perspetiva», diferente do utilizado num projeto Java clássico:

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

A perspetiva J2EE é, na verdade, desnecessariamente complexa para projetos web simples. Neste caso, a perspetiva Java é suficiente. Para a obter, utilizamos a opção [Window -> Open perspective -> Java]:

src: conterá o código Java das classes da aplicação, bem como os ficheiros que devem constar no Classpath da aplicação.
build/classes (não representado): conterá os ficheiros .class das classes compiladas, bem como uma cópia de todos os ficheiros que não sejam .java colocados em src. Uma aplicação web utiliza frequentemente ficheiros denominados «recursos», que devem estar no Classpath da aplicação, o c.a.d. O conjunto de pastas que são exploradas pelo JVM quando a aplicação faz referência a uma classe, seja durante a compilação, seja durante a execução. O Eclipse assegura que a pasta build/classes faça parte do c web. Colocam-se na pasta src os ficheiros «recursos», 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: conterá os arquivos .jar de que a aplicação web necessita.
Vamos analisar o conteúdo do ficheiro [WEB-INF/web.xml] que configura a aplicação [personne]:
<?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 iniciais no parágrafo 2.3.4. Este ficheiro não faz mais do que definir uma série de páginas iniciais. Mantemos apenas a primeira. O ficheiro [web.xml] fica assim:
<?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 obedecer às regras de sintaxe definidas no ficheiro designado pelo atributo [xsi:schemaLocation] da baliza de abertura <web-app>. Este ficheiro é, neste caso, o [http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd]. Trata-se de um ficheiro XML que pode ser acedido diretamente através de um navegador. Se este for suficientemente recente, conseguirá apresentar um ficheiro XML:

O Eclipse irá verificar a validade do documento XML utilizando o ficheiro .xsd especificado no atributo [xsi:schemaLocation] da baliza de abertura <web-app>. Para tal, irá efetuar um acesso à rede. Se o seu computador estiver numa rede privada, é necessário indicar ao Eclipse o servidor a utilizar para sair da rede privada, denominado proxy HTTP. Isto é feito através da opção [Window -> Preferences -> Internet]:

Marque a caixa (1) se estiver numa rede privada. Em (2), indique o nome do servidor que suporta o proxy HTTP e, em (3), a porta de escuta do mesmo. Por fim, em (4), indicam-se os computadores para os quais não é necessário passar pelo proxy, ou seja, os computadores que se encontram na mesma rede privada que o computador com o qual se está a trabalhar.
Vamos agora criar o ficheiro [index.html] da página inicial.
3.2. Criação de uma página inicial
Clicamos com o botão direito do rato na pasta [WebContent] e selecionamos a opção [New -> Other]:

Escolhemos o tipo [HTML] e transformamos [Next] em ->

Acima, selecionamos a pasta pai [WebContent] em (1) ou em (2) e, em seguida, especificamos em (3) o nome do ficheiro a criar. Feito isto, passamos 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. Mantemos a opção (1) marcada para obter um esboço de código. Concluímos o assistente com [Finish]. É então criado o ficheiro [index.html]:

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>
Alteramos 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. Teste da página inicial
Se não estiver presente, vamos abrir a vista [Servers] com a opção [Window - > Show View -> Other -> Servers] e, em seguida, clicar com o botão direito do rato no servidor Tomcat 5.5:

A opção [Add and Remove Objects] acima permite adicionar/remover aplicações web do servidor Tomcat:

Os projetos web reconhecidos pelo Eclipse são apresentados em (1). É possível registá-los no servidor Tomcat através de (2). As aplicações web registadas no servidor Tomcat aparecem em (4). É possível cancelar o registo através de (3). Vamos registar o projeto [personne]:

e, em seguida, concluamos o assistente de registo com [Finish]. A vista [Servers] mostra que o projeto [personne] foi registado no Tomcat:

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

e, em seguida, acedamos à URL [http://localhost:8080/personne]. Esta URL corresponde à 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, é apresentado um erro. Aqui, a página inicial existe. Trata-se do ficheiro [index.html] que criámos anteriormente. O resultado obtido é o seguinte:

Está de acordo com o esperado. Agora, vamos utilizar um navegador externo ao Eclipse e aceder à mesma URL:

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

Para o criar, seguiremos o procedimento descrito no parágrafo 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"> | txtNom | linha 14 | introdução do nome | |
<input type= "text "> | txtAge | linha 18 | introdução da idade | |
<input type= "submit "> | linha 23 | envio dos valores introduzidos para o servidor na URL /pessoa1/main | ||
<input type="reset"> | linha 24 | para repor a página no estado em que foi inicialmente recebida pelo navegador | ||
<input type="button"> | linha 25 | para limpar o conteúdo dos campos de introdução de dados [1] e [2] |
Vamos guardar o documento na pasta <pessoa>/WebContent. Iniciemos o Tomcat, se necessário. Num navegador, acedamos à página 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 fornece o mesmo conteúdo a cada pedido do cliente. A programação web tem como objetivo gerar conteúdo adaptado à solicitação do cliente. Esse conteúdo é, então, gerado por programa. Uma primeira solução consiste em utilizar uma página JSP (Java Server Page) em vez do ficheiro estático HTML. É isso que vamos ver agora.
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 é uma variante parametrizada da página HTML. Alguns elementos da página só recebem o seu valor no momento da execução. Estes valores são calculados pelo programa. Temos, portanto, uma página dinâmica: pedidos sucessivos à página podem resultar em respostas diferentes. Chamamos aqui de resposta a página HTML apresentada pelo navegador do cliente. No final, é sempre um documento HTML que o navegador recebe. Este documento HTML é gerado pelo servidor web a partir da página JSP. Esta última serve de modelo. Os seus elementos dinâmicos são substituídos pelos seus valores efetivos no momento da geração do documento HTML.
Para criar uma página JSP, clicamos com o botão direito do rato na pasta [WebContent] e selecionamos a opção [New -> Other]:

Escolhemos o tipo [JSP] e fazemos [Next] ->

Acima, selecionamos a pasta pai [WebContent] em (1) ou em (2) e, em seguida, especificamos em (3) o nome do ficheiro a criar. 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. Mantemos a opção (1) marcada para obter um esboço de código. Concluímos o assistente com [Finish]. É então criado o ficheiro [formulaire.jsp]:

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 perante 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">
<%
// recuperam-se os parâmetros
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:
- inserimos código Java logo no início do documento para recuperar os parâmetros necessários à sua visualização. Estes encontrar-se-ão frequentemente no objeto `request`. Este objeto representa o pedido do cliente. Este pedido pode passar por vários servlets e páginas JSP que o possam ter enriquecido. Neste caso, chegar-nos-á diretamente do navegador.
- O código HTML encontra-se a seguir. Na maioria das vezes, limitar-se-á a apresentar variáveis calculadas anteriormente no código Java, utilizando as tags <%= variável %>. Note-se aqui que o sinal = está colado ao sinal %. Esta é uma causa frequente de erros.
O que faz o documento dinâmico anterior?
- linhas 6-9: recupera da solicitação dois parâmetros 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 por defeito às variáveis associadas.
- Exibe o valor das duas variáveis [nom, age] no código HTML que se segue (linhas 25 e 29).
Vamos fazer um primeiro teste. Iniciemos o Tomcat, se necessário, e, em seguida, num navegador, acedamos à página http://localhost:8080/personne/formulaire.jsp:

O documento formulaire.jsp foi chamado sem a passagem de parâmetros. Por isso, foram apresentados os valores por predefinição. Agora, vamos solicitar o URL http://localhost:8080/personne/formulaire.jsp?txtNom=martin&txtAge=14:

Desta vez, passámos para o documento formulaire.jsp os parâmetros txtNom e txtAge que ele esperava. Por isso, ele exibiu-os. Sabemos que existem dois métodos para passar parâmetros a um documento web: GET e POST. Em ambos os casos, os parâmetros passados encontram-se no objeto predefinido request. Aqui, foram passados através do 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, a solicitação do cliente era processada por uma página JSP. Na primeira chamada a essa página, o servidor web, neste caso o Tomcat, cria uma classe Java a partir dessa página e compila-a. É o resultado dessa compilação que, em última análise, processa a solicitação 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 processada 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 na página JSP, o documento HTML enviado ao cliente era gerado pelo servidor web a partir da página JSP, que servia de modelo. Neste caso, o documento HTML enviado ao cliente será inteiramente gerado pelo servlet.
3.6.1. Criação do servlet
No Eclipse, cliquemos com o botão direito do rato na pasta [src] e selecionemos a opção para criar uma classe:

e, em seguida, definamos as características da classe a criar:

Em (1), introduz-se o nome do pacote; em (2), o nome da classe a criar. Esta deve derivar da classe indicada em (3). Não é necessário digitar manualmente o nome completo desta. O botão (4) permite aceder às classes atualmente presentes no Classpath da aplicação web:

Em (1), introduz-se o nome da classe procurada. Em (2), obtêm-se as classes do Classpath cujo nome contém a cadeia de caracteres introduzida em (1).
Após a validação do assistente de criação, o projeto web [personne] é alterado da seguinte forma:

A classe [ServletFormulaire] foi criada com um esboço de código:

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

Depois de clicar em (1), são-nos apresentadas em (2) soluções para eliminar o [warning]. Ao selecionar uma delas, surge em (3) a alteração de código que essa escolha irá implicar.
O Java 1.5 introduziu alterações na linguagem Java e o que era correto numa versão anterior pode agora ser alvo de [warnings]. Estes não sinalizam erros que possam impedir a compilação da classe. Estão lá para chamar a atenção do programador para pontos do código que poderiam ser melhorados. O [warning] aqui apresentado indica que uma classe deve ter um número de versão. Este é utilizado para a serialização/deserialização de objetos, c.a.d. quando um objeto Java .class na memória tem de ser transformado numa sequência de bits enviados sequencialmente num fluxo de escrita, ou o inverso, quando um objeto Java .class na memória tem de 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 solução [Add @SuppressWarnings ...]. O código passa então a ser o seguinte:

Já não existe o [warning]. A linha adicionada denomina-se «anotação», um conceito que surgiu com o Java 1.5. Completaremos este código posteriormente.
3.6.2. Classpath de um projeto Eclipse
O Classpath de uma aplicação Java é o conjunto de pastas e archives.jar exploradas quando o compilador a compila ou quando a JVM a executa. Estes dois Classpath não são necessariamente idênticos, uma vez que algumas classes só são úteis na execução e não na compilação. Tanto o compilador Java como o JVM dispõem de um argumento que permite especificar o Classpath da aplicação a compilar ou a executar. De forma mais ou menos transparente para o utilizador, o Eclipse assegura a construção e a passagem desse argumento para o JVM.
Como se pode conhecer os elementos do Classpath de um projeto Eclipse? Com a opção [<projet> / Build Path / Configure Build Path]:

Obtenemos então o seguinte assistente de configuração:

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

- [Tomcat v5.5 runtime]: biblioteca fornecida pelo servidor Tomcat. Contém as classes necessárias para o desenvolvimento web. Esta biblioteca está incluída em todos os projetos web do Eclipse que tenham sido associados ao servidor Tomcat.

É o arquivo [servlet-api.jar] que contém a classe [javax.servlet.http.HttpServlet], classe pai da classe [ServletFormulaire] que estamos a criar. É porque este arquivo se encontra no Classpath da aplicação que pôde ser sugerido como classe pai no assistente apresentado abaixo.

Se não fosse esse o caso, não teria aparecido nas sugestões para a [2]. Portanto, se, neste assistente, se pretender referenciar uma classe pai e esta não for sugerida, isso significa que, ou se está a cometer um erro no nome dessa classe, ou o arquivo que a contém não se encontra no Classpath da aplicação.
- O [Web App Libraries] reúne os arquivos presentes na pasta [WEB-INF/lib] do projeto. Neste caso, está vazio:

Os arquivos do Classpath do projeto Eclipse estão presentes no explorador de projetos. Por exemplo, para o projeto web [personne]:

O explorador de projetos permite-nos aceder ao conteúdo destes arquivos:

Assim, como se pode ver acima, é o arquivo [servlet-api.jar] que 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] serve para configurar a aplicação web:

Este ficheiro, para o projeto [personne], é atualmente o seguinte (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>
Indica apenas a existência de um ficheiro de página inicial (linha 8). Vamos alterá-lo para declarar:
- a existência do servlet [ServletFormulaire]
- os URL processados por esta servlet
- os parâmetros de inicialização do servlet
O ficheiro web.xml da nossa aplicação «pessoa» ficará assim:
<?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: a configuração de um servlet é feita entre as balizas <servlet> e </servlet>. Uma aplicação pode incluir vários servlets e, por conseguinte, o mesmo número de secções de configuração <servlet>...</servlet>.
- linha 8: a baliza <servlet-name> atribui um nome ao servlet — pode ser qualquer nome
- linhas 9-11: a baliza <servlet-class> indica o nome completo da classe correspondente ao servlet. O Tomcat irá procurar essa classe no Classpath do projeto web [personne]. Encontrá-la-á em [build/classes]:
![]()
- linhas 12-15: a baliza <init-param> serve para passar parâmetros de configuração para a servlet. Estes são geralmente lidos no método init da servlet, uma vez que os parâmetros de configuração desta devem ser conhecidos logo no seu primeiro carregamento.
- linhas 13-14: a baliza <param-name> define o nome do parâmetro e <param-value> o seu valor.
- as linhas 12-15 definem um parâmetro [defaultNom,"inconnu"] e as linhas 16-19 um parâmetro [defaultAge,"XXX"]
- linhas 21-24: a baliza <servlet-mapping> serve para associar um servlet (servlet-name) a um modelo de URL (url-pattern). Neste caso, o padrão é simples. Indica que sempre que um URL tiver o formato /formulário, deverá ser utilizado o servlet «formulário-pessoa», c.a.d, da classe [istia.st.servlets.ServletFormulaire] (linhas 8-11). Portanto, existe apenas uma URL aceite pelo servlet [formulairepersonne].
3.6.4. O código do servlet [ServletFormulaire]
O servlet [ServletFormulaire] terá o seguinte código:
Ao analisar a servlet, verifica-se que é muito mais complexa do que a página JSP correspondente. Trata-se de uma regra geral: uma servlet não é adequada para gerar código HTML. São as páginas JSP que se destinam a isso. Teremos oportunidade de voltar a este assunto. Vamos explicar alguns pontos importantes da servlet acima:
- quando uma servlet é chamada pela primeira vez, o seu método init (linha 20) é chamado. Este é o único caso em que é chamado.
- Se a servlet tiver sido chamada pelo método HTTP GET, o método doGet (linha 32) é chamado para processar o pedido do cliente.
- Se o servlet tiver sido chamado pelo método HTTP POST, o método doPost (linha 82) é chamado para processar o pedido do cliente.
O método init serve aqui para recuperar, no [web.xml], os valores dos parâmetros de inicialização denominados «defaultNom» e «defaultAge». O método init, executado no carregamento inicial do servlet, é 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, recupera-se o valor do tipo String do parâmetro denominado «defaultNom». Este parâmetro terá como valor o nome de uma pessoa. Se não existir, obter-se-á o valor null.
- linhas 24-25: se o parâmetro denominado «defaultNom» não existir, atribui-se um valor por defeito à variável [defaultNom].
- linhas 26-29: faz-se o mesmo para o parâmetro denominado «defaultAge».
O método doPost remete para o método doGet. Isto significa que o cliente poderá enviar os seus parâmetros tanto através de um POST como de um GET.
O método doGet:
- linha 32: o método recebe dois parâmetros, request e response. request é um objeto que representa a totalidade do pedido do cliente. É do tipo HttpServletRequest, que é uma interface. response é do tipo HttpServletResponse, que também é uma interface. O objeto response serve para enviar uma resposta ao cliente.
- request.getParameter("param") serve para recuperar, na solicitação do cliente, o valor do parâmetro com o nome «param». Na linha 36, recupera-se 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, obtém-se o valor null como valor do parâmetro.
- linhas 37-39: se o parâmetro «txtNom» não estiver presente na consulta, atribui-se à variável «nom» o nome por predefinição «defaultNom», inicializado no método init. O mesmo se aplica às linhas 41-43 para a idade.
- linha 45: response.setContentType(String) serve 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() serve para obter um fluxo de escrita para o cliente
- linhas 47-78: escreve-se o documento HTML a enviar ao cliente no fluxo de escrita obtido na linha 46.
A compilação deste servlet irá produzir um ficheiro .class na pasta [build/classes] do projeto [personne]:

Recomenda-se ao leitor que consulte a ajuda do Java sobre servlets. Para tal, pode recorrer ao Tomcat. Na página inicial do Tomcat 5, existe um link [Documentation]:

Este link conduz a uma página que o leitor é convidado a explorar. O link para a documentação sobre servlets é o seguinte:

3.6.5. Teste do servlet
Estamos prontos para fazer um teste. Vamos iniciar o servidor Tomcat, se necessário.

Em seguida, acedamos com um navegador a URL [http://localhost:8080/personne/formulaire]. Aqui, estamos a aceder à URL [/formulaire] do contexto [/personne]. O ficheiro [web.xml] deste contexto indica que a URL [/formulaire] é processada pelo servlet com o nome [formulairepersonne]. No mesmo ficheiro, indica-se que esta servlet corresponde à classe [istia.st.servlets.ServletFormulaire]. É, portanto, a esta classe que o Tomcat irá confiar o processamento do pedido do cliente. Se a classe ainda não estiver carregada, será carregada. Permanecerá então na memória para pedidos futuros.
Obtém-se o seguinte resultado com o navegador interno do Eclipse:

Obtemos os valores por predefinição do nome e da idade, os que estão registados no ficheiro [web.xml]. Vamos agora solicitar o URL [http://localhost:8080/personne/formulaire?txtNom=tintin&txtAge=30]:

Desta vez, obtemos os parâmetros passados na solicitação. O leitor é convidado a reler 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, alteremos o código do servlet da seguinte forma:
- a linha 8 foi alterada
Vamos guardar a nova classe. Este processo de gravação fará com que o Eclipse recompile automaticamente a classe [ServletFormulaire], o que o Tomcat irá detetar. Em seguida, irá recarregar o contexto da aplicação web [personne] para ter em conta as alterações. Isto aparece nos registos da vista [console]:

Vamos aceder à URL [http://localhost:8080/personne/formulaire] sem reiniciar o Tomcat:

A alteração efetuada foi efetivamente aplicada.
Agora, vamos alterar 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 alterada
Feito isto, guardemos o novo ficheiro [web.xml]. Na vista [console], nenhum registo indica a recarga do contexto da aplicação. Acedamos à URL [http://localhost:8080/personne/formulaire] sem reiniciar o Tomcat:

A alteração efetuada não foi tida em conta. Reiniciemos o Tomcat [clic droit sur serveur -> Restart -> Start]:

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

Desta vez, a alteração efetuada em [web.xml] está visível.
Uma alteração em [web.xml] não provoca, portanto, uma recarga automática da aplicação que tenha em conta o novo ficheiro de configuração. Para forçar a recarga da aplicação web, pode-se reiniciar o Tomcat, tal como fizemos, mas trata-se de uma operação bastante lenta. É preferível utilizar a ferramenta [manager] para a gestão das aplicações implementadas no Tomcat. Para que isso seja possível, é necessário que, no Eclipse, o Tomcat tenha sido configurado conforme demonstrado no parágrafo 2.5.
Em primeiro lugar, com o navegador interno do Eclipse, acedamos à URL [http://localhost:8080] e, em seguida, sigamos a ligação [Tomcat Manager], tal como explicado no final do parágrafo 2.5:

Abramos um segundo navegador [clic droit sur le navigateur -> New Editor]:
![]() | ![]() |
Neste segundo navegador, vamos aceder à URL [http://localhost:8080/formulaire]:

Vamos alterar o ficheiro [web.xml] da seguinte forma e, em seguida, guardá-lo:
<!-- 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, solicitemos novamente a URL [http://localhost:8080/formulaire]. Podemos constatar que a alteração não foi aplicada. Agora, vamos ao primeiro navegador e atualizemos a aplicação [personne]:

Em seguida, voltamos a aceder à URL [http://localhost:8080/formulaire] com o segundo navegador:

A alteração em [web.xml] foi aplicada. Na prática, é útil ter um navegador aberto na aplicação [manager] do Tomcat para gerir este tipo de situações.
3.7. Cooperação entre servlets e páginas JSP
Leituras [ref1]: capítulo 2: 2.3.7
Voltemos às duas arquiteturas analisadas:

Nenhuma destas duas arquiteturas é satisfatória. Ambas apresentam a desvantagem de misturar duas tecnologias: a programação Java, que se ocupa da lógica da aplicação web, e a codificação HTML, que se ocupa da apresentação de informações num navegador.
- A solução [1] baseada na página JSP tem a desvantagem de misturar código HTML e código Java na mesma página. Não observámos isso no exemplo analisado, que era básico. Mas se o [formulaire.jsp] tivesse de verificar a validade dos parâmetros [txtNom, txtAge] da solicitação do cliente, teríamos sido obrigados a incluir código Java na página. Isso torna-se rapidamente incontrolável.
- A solução [2] baseada em servlet apresenta o mesmo problema. Embora haja apenas código Java na classe, esta tem de 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.
Vamos evitar a mistura das tecnologias Java e HTML adotando a seguinte arquitetura:

- o utilizador envia o seu pedido para o servlet. Este processa-o e constrói os valores dos parâmetros dinâmicos da página JSP [formulaire.jsp], que servirão para gerar a resposta HTML para o cliente. Estes valores constituem o chamado modelo da página JSP.
- Assim que terminar o seu trabalho, o servlet solicitará às páginas JSP e [formulaire.jsp] que gerem a resposta HTML para o cliente. Ao mesmo tempo, irá fornecer-lhe os elementos de que a página JSP necessita para gerar essa resposta, elementos esses que constituem o modelo da página.
Vamos agora explorar esta nova arquitetura.
3.7.1. O servlet [ServletFormulaire2]
Na arquitetura acima, o servlet chamar-se-á [ServletFormulaire2]. Será criado no mesmo projeto [personne] que anteriormente, tal como todos os servlets futuros:

A [ServletFormulaire2] é obtida, em primeiro lugar, através de um copiar/colar da [ServletFormulaire] no Eclipse:
- selecionar [ServletFormulaire.java] -> clique com o botão direito do rato -> Copiar
- selecionar [istia.st.servlets.personne] -> clique com o botão direito do rato -> Colar -> alterar o nome para [ServletFormulaire2.java]
Em seguida, alteramos o código de [ServletFormulaire2] da seguinte forma:
Apenas a parte relativa à geração da resposta HTTP foi alterada (linhas 44-46):
- linha 46: a geração da resposta é atribuída à página JSP formulaire2.jsp. Esta página, que ainda não foi analisada, será responsável por apresentar os parâmetros recuperados na solicitação do cliente: um nome (linhas 35-38) e uma idade (linhas 39-42).
- Estes dois valores são colocados nos atributos da solicitação [request], associados a chaves. Os atributos de uma solicitação são geridos como um dicionário.
- linha 44: o nome é inserido na consulta associado à chave «nome»
- linha 45: a idade é inserida na consulta associada à chave «idade»
- linha 46: solicita a exibição da página JSP [formulaire2.jsp]. São passados como parâmetros para esta:
- a consulta [request] do cliente, o que permitirá que a página JSP tenha acesso aos atributos da mesma, que acabaram de ser inicializados pelo servlet
- a resposta [response], que permitirá que a página JSP gere 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 é obtida através de copiar/colar a partir da página [formulaire.jsp]

e, em seguida, transformada 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">
<%
// recuperam-se os valores necessários para a visualização
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 a 8 sofreram alterações em relação a [formulaire.jsp]:
- linha 6: recupera o valor do atributo denominado «nom» na consulta [request], atributo criado pelo servlet [ServletFormulaire2].
- linha 7: faz o mesmo para o atributo «idade»
3.7.3. Configuração da aplicação
O ficheiro de configuração [web.xml] é alterado 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>
<!-- Mapeamento ServletFormulaire -->
<servlet-mapping>
<servlet-name>formulairepersonne</servlet-name>
<url-pattern>/formulaire</url-pattern>
</servlet-mapping>
<!-- Mapeamento ServletFormulaire 2-->
<servlet-mapping>
<servlet-name>formulairepersonne2</servlet-name>
<url-pattern>/formulaire2</url-pattern>
</servlet-mapping>
<!-- ficheiros de acolhimento -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Mantivemos o que já existia 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 lhe associar o URL /formulário2
Inicie ou reinicie o servidor Tomcat, se necessário. Solicitamos o URL
http://localhost:8080/personne/formulaire2?txtNom=milou&txtAge=10:

Obtenemos o mesmo resultado que anteriormente, 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 uma página JSP o envio da resposta ao cliente. A partir de agora, procederemos sempre desta forma.



