10. Aplicação web MVC [personne] – versão 5
10.1. Introduction
Nesta versão, introduzimos duas alterações:
A primeira diz respeito à forma como o cliente indica ao servidor a ação que pretende realizar. Até agora, esta era especificada através de um parâmetro denominado [action] na solicitação do GET ou do POST do cliente. Neste caso, a ação será especificada pelo último elemento do URL solicitado pelo cliente, tal como mostra a sequência seguinte:

Em [1], a URL para a qual o formulário foi enviado é [/personne5/do/validationFormulaire]. Foi o último elemento, [validationFormulaire], da URL que permitiu ao controlador reconhecer a ação a realizar. Em [2], o POST, provocado pelo link [Retour au formulaire], foi realizado na URL [/personne5/do/retourFormulaire]. Mais uma vez, o último elemento [retourFormulaire] da URL indica ao controlador a ação a realizar.
Estamos a introduzir esta alteração porque este é o método utilizado pelos frameworks de desenvolvimento web mais comuns, tais como o Struts ou o Spring MVC.
Todas as URLs da aplicação terão o formato [/personne5/do/action]. O ficheiro [web.xml] da aplicação [/personne5] indicará que esta aceita URLs com o formato [/do/*]:
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
O controlador irá recuperar o nome da ação a realizar da seguinte forma:
O método [getPathInfo] do objeto [request] fornece o último elemento da URL do pedido.
A segunda alteração introduzida diz respeito à forma de armazenar as entradas feitas pelo utilizador entre dois ciclos de pedido/resposta. Atualmente, estas informações são armazenadas numa sessão. Este método pode apresentar desvantagens se houver muitos utilizadores e muitos dados a armazenar para cada um deles. Com efeito, cada utilizador tem a sua sessão pessoal. Além disso, esta permanece ativa durante algum tempo após a saída de um utilizador, a menos que se tenha tido o cuidado de lhe oferecer uma opção de desligar a sessão. Assim, 1000 sessões de 1000 octetos ocuparão 1 Mo de memória. Trata-se de uma exigência moderada e há poucas aplicações que tenham 1000 sessões ativas simultaneamente.
No entanto, existem alternativas à sessão, menos exigentes em termos de memória, e é bom conhecê-las. Aqui, utilizaremos o método dos cookies. Vamos ilustrá-lo com um exemplo.
Passo 1: o utilizador submete um formulário:
![]() |
Este ciclo de pedido/resposta dá origem às seguintes trocas HTTP entre o cliente e o servidor:
[1] : [demande du client]
Trata-se de um POST clássico. Não há nada de especial a assinalar aqui, a não ser que, embora não se vá utilizar uma sessão, o servidor web cria uma na mesma. Isso é visível no token de sessão que o navegador reenvia ao servidor na linha 11 e que tinha recebido anteriormente do servidor.
[2]: [réponse du serveur]
Vemos que, nas linhas 3 e 4, foram enviados ao navegador do cliente os cabeçalhos HTTP e [Set-Cookie], um para o nome (linha 3) e outro para a idade (linha 4). Os valores destes cookies são os valores enviados na linha 14 dos POST e [1] acima referidos.
Passo 2: Regresso ao formulário

Este ciclo de pedido/resposta dá origem às seguintes trocas HTTP entre o cliente e o servidor:
[1]: [demande du client]
Assistimos aqui ao POST provocado pelo clique no link [Retour au formulaire]. Na linha 11, vemos que o navegador reenvia ao servidor os cookies que recebeu ([nom, age, JSESSIONID]) através do cabeçalho HTTP [Cookie]. Este é o princípio dos cookies. O cliente reenvia ao servidor os cookies que este lhe enviou. Neste exemplo, o controlador irá receber os valores [pauline, 18], que deve colocar nos campos [txtNom, txtAge] da vista [formulaire] apresentada em [2].
[2]: [réponse du serveur]
Não há aqui nada de especial a assinalar, para além do facto de, nesta resposta, o servidor não ter enviado cookies. Isso não impedirá o navegador de reenviar, na próxima troca de dados, todos os cookies que recebeu do servidor, mesmo que isso não sirva para nada. Reduz-se, assim, a pressão sobre a memória disponível do servidor, à custa de um aumento do fluxo de caracteres nas trocas cliente/servidor.
10.2. O projeto Eclipse
Para criar o projeto Eclipse [mvc-personne-05] da aplicação web [/personne5], duplicaremos o projeto [mvc-personne-04], seguindo o procedimento descrito no parágrafo 6.2.
![]() | ![]() |
10.3. Configuração da aplicação web [personne5]
O ficheiro web.xml da aplicação /personne5 é o seguinte:
<?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>mvc-personne-05</display-name>
<!-- ServletPersonne -->
<servlet>
<servlet-name>personne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletPersonne
</servlet-class>
...
</servlet>
<!-- Mapeamento ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
<!-- ficheiros de início -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Este ficheiro é idêntico ao da versão anterior, com exceção de alguns detalhes:
- linha 6: o nome de exibição da aplicação web mudou para [mvc-personne-05]
- linha 18: as URLs processadas pela aplicação têm o formato [/do/*]. Anteriormente, apenas a URL [/main] era processada. Agora, existem tantas URLs quantas as ações a processar.
A página inicial [index.jsp] altera-se:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
<c:redirect url="/do/formulaire"/>
- linha 5: a página [index.jsp] redireciona o cliente para a URL [/personne5/do/formulaire], o que equivale a solicitar ao controlador que execute a ação [formulaire].
10.4. O código das vistas
As vistas [formulaire, réponse, erreurs] sofrem poucas alterações. A única alteração deve-se ao facto de a ação a realizar já não ser especificada da mesma forma que anteriormente, quando era definida num campo oculto denominado [action] dos formulários enviados. Agora, é definida no URL de destino dos formulários enviados, c.a.d, no atributo [action] da tag <form>:
[formulaire.jsp]:
...
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
...
</script>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form name="frmPersonne" action="validationFormulaire" method="post">
...
</form>
</center>
</body>
</html>
- linha [13]: o parâmetro [action] do formulário reaparece após ter desaparecido durante algum tempo nas versões anteriores. Para compreender o valor deste atributo aqui, é necessário lembrar que todas as URLs processadas pela aplicação têm o formato [/do/action]. Na linha [13], o atributo [action] tem como valor uma URL relativa (que não começa por /). Assim, o navegador irá completá-la com a URL da página atualmente exibida, ou seja, necessariamente uma URL com o formato [/do/action]. O último elemento será substituído pela URL relativa do atributo [action] da baliza <form>, resultando na URL [/do/validationFormulaire] como destino do POST.
- O campo oculto [action] desapareceu
[réponse.jsp]:
...
<html>
...
<body>
...
<form name="frmPersonne" action="retourFormulaire" method="post">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
- linha [7]: o destino do POST será o [/do/retourFormulaire]
- o campo oculto [action] desapareceu no formulário das linhas 7-8.
[erreurs.jsp]:
...
<html>
...
<body>
...
<form name="frmPersonne" action="retourFormulaire" method="post">
</form>
<a href="javascript:document.frmPersonne.submit();">
${lienRetourFormulaire}
</a>
</body>
</html>
- linha [6]: o destino do POST será [/do/retourFormulaire]
- o campo oculto [action] desapareceu no formulário das linhas 6-7.
Convida-se o leitor a testar estas novas vistas de acordo com o princípio apresentado nas versões anteriores.
10.5. O controlador [ServletPersonne]
O controlador [ServletPersonne] da aplicação web [/personne5] irá processar as seguintes ações:
n.º | pedido | origem | processamento |
1 | [GET /personne5/do/formulaire] | URL introduzida pelo utilizador | - enviar a vista [formulaire] vazia |
2 | [POST /pessoa5/do/validationFormulaire] com os parâmetros [txtNom, txtAge] publicados | clicando no botão [Envoyer] na vista [formulaire] | - verificar os valores dos parâmetros [txtNom, txtAge] - se estiverem incorretos, enviar a vista [erreurs(erreurs)] - se estiverem corretos, enviar a vista [reponse(nom,age)] |
3 | [POST /pessoa5/para/retourFormulaire] sem parâmetros enviados | clique na ligação [Voltar ao formulário] das visualizações [réponse] e [erreurs]. | - enviar a vista [formulaire] pré-preenchida com os últimos valores introduzidos |
A estrutura do controlador [ServletPersonne] é idêntica à da versão anterior. Analisamos as alterações introduzidas nos métodos [doValidationFormulaire, doRetourFormulaire, doGet], uma vez que os métodos [init, doInit, doPost] não sofreram alterações.
10.5.1. O método [doGet]
O método [doGet] não recupera a ação a executar da mesma forma que nas versões anteriores:
- linha 12: recupera-se a ação a executar. Tem o formato [/action].
- linhas 18-22: processamento da ação [/formulaire] solicitada por uma solicitação GET
- linhas 23-27: processamento da ação [/validationFormulaire] solicitada por uma solicitação POST
- linhas 28-32: processamento da ação [/retourFormulaire] solicitada por uma requisição POST
10.5.2. O método [doValidationFormulaire]
Este método processa a solicitação n.º 2 [POST /personne5/do/validationFormulaire] com [txtNom, txtAge] nos elementos enviados. O seu código é o seguinte:
Novidades:
- o método [doValidationFormulaire] envia como resposta uma das vistas [réponse, erreurs]. Independentemente dessa resposta, o controlador insere nela dois cookies, linhas 8-9. Um cookie é representado por um objeto [Cookie], cujo construtor aceita dois parâmetros: a chave do cookie e o valor associado a ela.
- linha 8: o valor introduzido para o nome é colocado num cookie com a chave «nom»
- linha 9: o valor introduzido para a idade é colocado num cookie com a chave «idade»
- É adicionado um cookie à resposta HTTP enviada ao cliente através do método [response.addCookie]. Esta resposta é, neste caso, apenas preparada. Só será efetivamente enviada quando a página JSP da vista enviada ao cliente for executada.
10.5.3. O método [doRetourFormulaire]
Este método processa o pedido n.º 2 [POST /personne5/do/retourFormulaire] sem elementos enviados. O seu código é o seguinte:
Novidades:
O método [doRetourFormulaire] deve apresentar um formulário pré-preenchido com as últimas entradas efetuadas. Na versão anterior, estas estavam na sessão. Nesta versão, já não se utiliza a sessão, mas sim cookies para memorizar elementos entre duas trocas cliente-servidor. Quando o cliente solicitou a validação do formulário, recebeu como resposta a vista [réponse] ou [erreurs], consoante o caso, acompanhada de dois cookies denominados «nome» e «idade». Ao clicar na ligação [Retour au formulaire] destas duas vistas, o que provoca a exibição de POST na URL [/do/retourFormulaire], o navegador reenvia ao servidor os dois cookies que recebeu.
- linhas 4-18: recuperam-se os valores dos cookies denominados «nome» e «idade». Curiosamente, não existe um método que permita obter o valor de um cookie a partir da sua chave. Por isso, é necessário analisar cada um dos cookies recebidos.
- Feito isto, os dois valores obtidos são colocados no modelo da vista [formulaire] (linhas 20-21) para que esta os exiba.
10.6. Tests
Inicie ou reinicie o Tomcat após ter integrado o projeto Eclipse [personne-mvc-05] e, em seguida, aceda à URL [http://localhost:8080/personne5].


