10. Aplicação Web MVC [person] – Versão 5
10.1. Introdução
Nesta versão, estamos a fazer duas alterações:
A primeira diz respeito à forma como o cliente indica ao servidor a ação que pretende realizar. Até agora, isto era especificado utilizando um parâmetro chamado [action] no pedido GET ou POST do cliente. Aqui, a ação será especificada pelo último elemento do URL solicitado pelo cliente, conforme mostrado na sequência seguinte:

Em [1], a URL para a qual o formulário foi enviado é [/person5/do/validateForm]. É o último elemento [validateForm] da URL que permitiu ao controlador reconhecer a ação a ser realizada. Em [2], o POST acionado pelo link [Voltar ao formulário] foi enviado para a URL [/person5/do/returnForm]. Aqui, mais uma vez, o último elemento [returnForm] da URL indica ao controlador qual ação deve ser executada.
Estamos a introduzir esta alteração porque é o método utilizado pelas estruturas de desenvolvimento web mais utilizadas, tais como Struts ou Spring MVC.
Todas as URLs na aplicação terão o formato [/person5/do/action]. O ficheiro [web.xml] da aplicação [/person5] especificará que aceita URLs do 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 ser executada da seguinte forma:
O método [getPathInfo] do objeto [request] devolve o último elemento do URL do pedido.
A segunda alteração diz respeito à forma como as entradas do utilizador são armazenadas entre os ciclos de pedido/resposta. Atualmente, esta informação é armazenada numa sessão. Esta abordagem pode ter desvantagens se houver muitos utilizadores e uma grande quantidade de dados a armazenar para cada um. De facto, cada utilizador tem a sua própria sessão pessoal. Além disso, a sessão permanece ativa durante algum tempo após o utilizador terminar a sessão, a menos que tenha sido fornecida uma opção de encerramento. Assim, 1 000 sessões de 100 bytes cada ocuparão 1 MB de memória. Este continua a ser um requisito moderado, e poucas aplicações têm 1 000 sessões ativas simultaneamente.
No entanto, existem alternativas às sessões que consomem menos memória, e é bom estar ciente delas. Aqui, utilizaremos o método dos cookies. Vamos ilustrar isto com um exemplo.
Passo 1: O utilizador envia um formulário:
![]() |
Este ciclo de solicitação/resposta resulta nas seguintes trocas HTTP entre o cliente e o servidor:
[1]: [solicitação do cliente]
Esta é uma solicitação POST padrão. Não há nada de invulgar a destacar aqui, exceto que, embora não vamos utilizar uma sessão, o servidor web cria uma na mesma. Isto é evidente a partir do token de sessão que o navegador reenvia ao servidor na linha 11, o qual tinha recebido anteriormente do servidor.
[2]: [resposta do servidor]
Podemos ver que nas linhas 3 e 4, foram enviados cabeçalhos HTTP [Set-Cookie] para o navegador do cliente, 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 do POST [1] acima.
Passo 2: Voltar ao formulário

Este ciclo de pedido/resposta resulta nas seguintes trocas HTTP entre o cliente e o servidor:
[1]: [solicitação do cliente]
Aqui vemos o pedido POST desencadeado ao clicar na ligação [Voltar ao formulário]. Na linha 11, vemos que o navegador reenvia os cookies que recebeu [name, age, JSESSIONID] para o servidor utilizando o cabeçalho HTTP [Cookie]. É assim que os cookies funcionam. O cliente reenvia para o servidor os cookies que o servidor lhe enviou. Neste exemplo, o controlador receberá os valores [pauline, 18], que deve colocar nos campos [txtName, txtAge] da vista [form] apresentada em [2].
[2]: [resposta do servidor]
Não há nada de especial a destacar aqui, além do facto de, nesta resposta, o servidor não ter enviado quaisquer cookies. Isto não impedirá o navegador de reenviar todos os cookies que recebeu do servidor na próxima troca, mesmo que isso não tenha qualquer utilidade. Reduzimos, assim, a carga sobre a memória disponível do servidor, à custa de um aumento no fluxo de caracteres nas trocas cliente/servidor.
10.2. O projeto Eclipse
Para criar o projeto Eclipse [mvc-personne-05] para a aplicação web [/personne5], duplique o projeto [mvc-personne-04] seguindo o procedimento descrito na secção 6.2.
![]() | ![]() |
10.3. Configurar a aplicação web [personne5]
O ficheiro web.xml para a 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>
<!-- Mapping ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/do/*</url-pattern>
</servlet-mapping>
<!-- welcome files -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Este ficheiro é idêntico ao da versão anterior, exceto por alguns detalhes:
- linha 6: o nome de exibição da aplicação web mudou para [mvc-personne-05]
- linha 18: os URLs tratados pela aplicação têm o formato [/do/*]. Anteriormente, apenas o URL [/main] era tratado. Agora, existem tantos URLs quantas as ações a tratar.
A página inicial [index.jsp] muda:
<%@ 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 [/person5/do/form], o que equivale a solicitar ao controlador que execute a ação [form].
10.4. O código da vista
As visualizações [form, response, errors] mudam muito pouco. A única alteração é que a ação a ser executada já não é especificada da mesma forma que antes, quando era definida num campo oculto denominado [action] nos formulários enviados. Agora é definida no URL de destino dos formulários enviados, ou seja, no atributo [action] da tag <form>:
[form.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 estado ausente durante algum tempo nas versões anteriores. Para compreender o valor deste atributo aqui, lembre-se de que todos os URLs processados pela aplicação têm o formato [/do/action]. Na linha [13], o atributo [action] tem como valor um URL relativo (que não começa por /). Portanto, o navegador irá completá-lo com a URL da página atualmente exibida, que é necessariamente uma URL do formato [/do/action]. O último elemento será substituído pela URL relativa do atributo [action] da tag <form> para produzir a URL [/do/validationFormulaire] como destino do POST.
- O campo oculto [action] desapareceu
[response.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á [/do/returnForm]
- O campo oculto [action] foi removido do formulário nas linhas 7–8.
[errors.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/returnForm]
- O campo oculto [action] foi removido do formulário nas linhas 6–7.
Convidamos os leitores a testarem estas novas visualizações utilizando a abordagem apresentada nas versões anteriores.
10.5. O controlador [ServletPersonne]
O controlador [ServletPersonne] da aplicação web [/personne5] irá tratar das seguintes ações:
N.º | pedido | origem | processamento |
1 | [GET /person5/do/form] | URL introduzida pelo utilizador | - enviar a vista [form] vazia |
2 | [POST /person5/do/formValidation] com os parâmetros [txtName, txtAge] enviado | clique no [Enviar] no [formulário] | - verifique os valores dos parâmetros [txtName, txtAge] - se estiverem incorretos, envie a vista [errors(errors)] - se estiverem corretos, envie a visualização [response(name,age)] |
3 | [POST /person5/do/returnForm] sem parâmetros enviados | Clique no [Voltar ao formulário] a partir da [resposta] e [erros]. | - enviar a vista [formulário] pré-preenchida com os valores introduzidos mais recentemente |
A estrutura do controlador [ServletPersonne] é idêntica à da versão anterior. Iremos rever as alterações feitas aos métodos [doValidationFormulaire, doRetourFormulaire, doGet]; os métodos [init, doInit, doPost] permanecem inalterados.
10.5.1. O método [doGet]
O método [doGet] não recupera a ação a ser executada da mesma forma que nas versões anteriores:
- linha 12: recuperar a ação a ser executada. Está no formato [/action].
- linhas 18–22: processamento da ação [/form] solicitada por uma solicitação GET
- linhas 23–27: processamento da ação [/validateForm] solicitada por uma solicitação POST
- linhas 28–32: processamento da ação [/returnForm] solicitada por uma solicitação POST
10.5.2. O método [doValidationFormulaire]
Este método processa a solicitação n.º 2 [POST /person5/do/validationFormulaire] com [txtName, txtAge] nos elementos enviados. O seu código é o seguinte:
Novidades:
- O método [doValidationFormulaire] devolve uma das vistas [response, errors]. Independentemente da resposta, o controlador define dois cookies no seu interior, 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 «name»
- linha 9: o valor introduzido para a idade é colocado num cookie com a chave "age"
- Um cookie é adicionado à resposta HTTP enviada ao cliente utilizando o método [response.addCookie]. Esta resposta é apenas preparada aqui. 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 /person5/do/retourFormulaire] sem quaisquer dados enviados. O seu código é o seguinte:
Novidades:
O método [doRetourFormulaire] deve apresentar um formulário pré-preenchido com os dados mais recentes. Na versão anterior, estes eram armazenados na sessão. Nesta versão, já não utilizamos a sessão, mas sim cookies para armazenar dados entre as trocas cliente-servidor. Quando o cliente solicitava a validação do formulário, recebia a vista [response] ou [errors] em resposta, conforme o caso, juntamente com dois cookies denominados «name» e «age». Quando o link [Voltar ao formulário] nestas duas vistas é clicado — o que desencadeia um pedido POST para o URL [/do/retourFormulaire] — o navegador reenvia os dois cookies que recebeu para o servidor.
- Linhas 4–18: Recuperamos os valores dos cookies denominados «name» e «age». Curiosamente, não existe um método para recuperar o valor de um cookie com base na sua chave. Por isso, temos de percorrer cada um dos cookies recebidos.
- Feito isso, os dois valores obtidos são colocados no modelo da vista [form] (linhas 20–21) para que este os possa apresentar.
10.6. Testes
Inicie ou reinicie o Tomcat após integrar o projeto Eclipse [person-mvc-05] nele e, em seguida, solicite a URL [http://localhost:8080/personne5].


