7. Aplicação Web MVC [person] – Versão 3
Leitura recomendada em [ref1]: Capítulo 9
7.1. Introdução
Propomos a inclusão de código JavaScript nas páginas HTML enviadas ao navegador. É o navegador que executa o código JavaScript incorporado na página que apresenta. Esta tecnologia é independente da utilizada pelo servidor web para gerar o documento HTML (Java/servlets/JSP, ASP.NET, ASP, PHP, Perl, Python, ...).
[form.jsp]
A visualização gerada a partir desta página terá o seguinte aspeto:

Os botões com o texto numa caixa utilizam código JavaScript incorporado na página HTML:
Rótulo | Tipo de HTML | Função |
<submit> | Funciona como o botão [Submeter] nas versões anteriores: envia os valores introduzidos para o controlador | |
<button> | Novo botão – verifica a validade dos dados introduzidos localmente antes de os enviar para o controlador | |
<reset> | redefine o formulário para o estado em que foi inicialmente recebido pelo navegador | |
<button> | limpa o conteúdo de ambos os campos de entrada |
Aqui está um exemplo de como utilizar os botões [Submit] e [Clear]:
![]() | ![]() |
![]() | ![]() |
Também utilizaremos código JavaScript para gerir o link [Voltar ao formulário] nas vistas [errors] e [response]. Tomemos a vista [response] como exemplo:
![]() | 1 ![]() |
A diferença reside no URL apresentado em [1]. Na versão anterior, era:
Aqui, a ação já não faz parte do URL porque será enviada através de um pedido POST em vez de um pedido GET. Esta alteração significa que o único URL apresentado pelo navegador será [http://localhost:8080/personne3/main], independentemente da ação solicitada.
7.2. O projeto Eclipse
Para criar o projeto Eclipse [mvc-personne-03] para a aplicação web [/personne3], duplique o projeto [mvc-personne-02] seguindo o procedimento descrito na secção 6.2, página 78.
![]() | ![]() |
7.3. Configurar a aplicação web [personne3]
O ficheiro web.xml para a aplicação /personne3 é 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-03</display-name>
<!-- ServletPersonne -->
<servlet>
<servlet-name>personne</servlet-name>
<servlet-class>
istia.st.servlets.personne.ServletPersonne
</servlet-class>
<init-param>
<param-name>urlReponse</param-name>
<param-value>
/WEB-INF/vues/reponse.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlErreurs</param-name>
<param-value>
/WEB-INF/vues/erreurs.jsp
</param-value>
</init-param>
<init-param>
<param-name>urlFormulaire</param-name>
<param-value>
/WEB-INF/vues/formulaire.jsp
</param-value>
</init-param>
<init-param>
<param-name>lienRetourFormulaire</param-name>
<param-value>
Retour au formulaire
</param-value>
</init-param>
</servlet>
<!-- Mapping ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/main</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-03]
O parâmetro [urlController] foi removido. Na versão anterior, era utilizado para definir o destino POST para a vista [form]. Nesta nova versão, o destino será a string vazia, ou seja, o URL exibido pelo navegador. Explicámos que este seria sempre [http://localhost:8080/personne3/main], que é o que precisamos para o pedido POST da vista [form].
A página inicial [index.jsp] muda:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
response.sendRedirect("/personne3/main");
%>
- Linha 5: A página [index.jsp] redireciona o cliente para o URL do controlador [ServletPersonne] na aplicação [/personne3].
7.4. O código da vista
7.4.1. A visualização [form]
Esta vista ficou assim:

É gerada pela seguinte página JSP [formulaire.jsp]:
<%@ 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 données du modèle
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
// -------------------------------
function effacer(){
// on efface les champs de saisie
with(document.frmPersonne){
txtNom.value="";
txtAge.value="";
}//with
}//effacer
// -------------------------------
function envoyer(){
// vérification des paramètres avant de les envoyer
with(document.frmPersonne){
// le nom ne doit pas être vide
champs=/^\s*$/.exec(txtNom.value);
if(champs!=null){
// le nom est vide
alert("Vous devez indiquer un nom");
txtNom.value="";
txtNom.focus();
// retour à l'interface visuelle
return;
}//if
// l'âge doit être un entier positif
champs=/^\s*\d+\s*$/.exec(txtAge.value);
if(champs==null){
// l'âge est incorrect
alert("Age incorrect");
txtAge.focus();
// retour à l'interface visuelle
return;
}//if
// les paramètres sont corrects - on les envoie au serveur
submit();
}//with
}//envoyer
</script>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form name="frmPersonne" 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>
<tr>
</table>
<table>
<tr>
<td><input type="submit" value="Submit"></td>
<td><input type="button" value="[Envoyer]" onclick="envoyer()"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="[Effacer]" onclick="effacer()"></td>
</tr>
</table>
<input type="hidden" name="action" value="validationFormulaire">
</form>
</center>
</body>
</html>
Novidades:
- Linha 56: O formulário tem o nome [frmPersonne]. Este nome será utilizado no código JavaScript. Repare na ausência do atributo [action], o que significa que o formulário [frmPersonne] será enviado para o URL apresentado pelo navegador.
- Linha 70: O botão [Submit] tem a mesma função que o botão [Envoyer] nas versões anteriores
- Linha 71: Ao clicar no botão [Envoyer] (do tipo [Button]), é executada a função JavaScript [envoyer] definida na linha 24
- Linha 72: O botão [Reset] não alterou a sua função
- Linha 73: Ao clicar no botão [Clear] (tipo [Button]), é executada a função JavaScript [clear] definida na linha 16
Antes de comentar o código JavaScript, vamos rever algumas convenções:
O JavaScript gere a página apresentada e o seu conteúdo como uma árvore de objetos cuja raiz é o objeto [document]. Este documento pode conter um ou mais formulários. [document.frmPersonne] refere-se ao formulário denominado [frmPersonne] definido na linha 56. Este formulário também contém objetos. Os campos de entrada fazem parte dele. Assim, [document.frmPersonne.txtName] refere-se ao objeto que representa o campo de entrada HTML definido na linha 60. O objeto [txtName] possui várias propriedades, incluindo a propriedade [value], que se refere ao conteúdo do campo de entrada. Assim, [document.frmPersonne.txtName.value] refere-se ao conteúdo do campo de entrada [txtName].
- linhas 16–22: A função JavaScript [clear] define uma cadeia de caracteres vazia nos campos de entrada [txtName, txtAge].
- Linhas 24–49: A função JavaScript [submit] verifica a validade dos valores nos campos de entrada [txtName, txtAge] antes de os enviar. Para tal, utiliza expressões regulares.
- Linha 28: Verifica se o valor do campo de entrada [txtNom] corresponde ao padrão /s*, o que significa zero ou mais espaços. Se a resposta for sim, isso significa que o utilizador não introduziu um nome. Se houver uma correspondência com o padrão, a variável `champs` terá um valor diferente do ponteiro nulo; caso contrário, terá o valor nulo.
- Linha 29: Se houver uma correspondência com o padrão
- Linha 30: Exibe uma mensagem ao utilizador
- linha 32: definimos o campo [txtName] como uma cadeia vazia (poderia ter havido uma sequência de espaços)
- linha 33: o cursor intermitente é posicionado no campo [txtName]
- linha 34: a função é encerrada. Os valores introduzidos não são, portanto, enviados para o servidor.
- Linhas 38–45: Seguimos um procedimento semelhante com o campo [txtAge]
- Linha 47: Se chegarmos a este ponto, significa que os valores introduzidos estão corretos. Em seguida, enviamos o formulário [frmPersonne] para o servidor web. Tudo prossegue então como se tivéssemos clicado no botão [Submit].
7.4.2. A vista [reponse]
Esta vista apresenta os valores introduzidos no formulário quando estes são válidos:
![]() | ![]() |
Em comparação com a versão anterior, a nova funcionalidade só aparece quando utiliza o link [Voltar ao formulário] na vista [resposta]:
![]() | ![]() |
A diferença reside no URL apresentado em [1]. Na versão anterior, era:
Aqui, a ação já não faz parte do URL porque será enviada através de um pedido POST em vez de um pedido GET. A nova página JSP [reponse.jsp] é lqqqaaaaaaaaaqqAAAaaa
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 données du modèle
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Personne - réponse</h2>
<hr>
<table>
<tr>
<td>Nom</td>
<td><%= nom %>
</tr>
<tr>
<td>Age</td>
<td><%= age %>
</tr>
</table>
<br>
<form name="frmPersonne" method="post">
<input type="hidden" name="action" value="retourFormulaire">
</form>
<a href="javascript:document.frmPersonne.submit();">
<%= lienRetourFormulaire %>
</a>
</body>
</html>
Novidades:
- linhas 35-37: o link [Voltar ao formulário] contém JavaScript. Clicar neste link aciona a execução do código JavaScript no atributo [href]. Como vimos no estudo de [formulaire.jsp], sabemos que este código envia os valores dos campos <input>, <select>, ... do formulário [frmPersonne].
- Linhas 32–34: definem o formulário [frmPersonne]. Este formulário tem apenas um campo do tipo <input type="hidden" ...>, ou seja, um campo oculto. Este campo [action] é utilizado para passar o nome da ação a ser executada para o controlador, neste caso [retourFormulaire].
7.4.3. A vista [errors]
Esta vista reporta erros de entrada no formulário. A alteração efetuada é a mesma que para a vista [response]:
![]() | ![]() |
A diferença reside no URL apresentado em [1]. Na versão anterior, era:
Aqui, a ação já não faz parte do URL porque será enviada através de um pedido POST em vez de um pedido GET. A nova página JSP [response.jsp] é a seguinte:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>
<%
// on récupère les données du modèle
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
<html>
<head>
<title>Personne</title>
</head>
<body>
<h2>Les erreurs suivantes se sont produites</h2>
<ul>
<%
for(int i=0;i<erreurs.size();i++){
out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
}//for
%>
</ul>
<br>
<form name="frmPersonne" method="post">
<input type="hidden" name="action" value="retourFormulaire">
</form>
<a href="javascript:document.frmPersonne.submit();">
<%= lienRetourFormulaire %>
</a>
</body>
</html>
Novidades:
- Linhas 30-32: o novo tratamento dos cliques nos links. As explicações fornecidas sobre este tema no estudo de [response.jsp] também se aplicam aqui.
7.5. Teste de visualização
Para testar as visualizações anteriores, duplicamos as suas páginas JSP na pasta /WebContent/JSP do projeto Eclipse:

Em seguida, na pasta JSP, as páginas são modificadas da seguinte forma:
[form.jsp]:
...
<%
// -- test : on crée le modèle de la page
session.setAttribute("nom","tintin");
session.setAttribute("age","30");
%>
<%// on récupère les données du modèle
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
As linhas 4–5 foram adicionadas para criar o modelo exigido pela página nas linhas 9–10.
[reponse.jsp]:
...
<%
// -- test : on crée le modèle de la page
request.setAttribute("nom","milou");
request.setAttribute("age","10");
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// on récupère les données du modèle
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
...
As linhas 4–6 foram adicionadas para criar o modelo exigido pela página nas linhas 11–13.
[errors.jsp]:
<%
// -- test : on crée le modèle de la page
ArrayList<String> erreurs1=new ArrayList<String>();
erreurs1.add("erreur1");
erreurs1.add("erreur2");
request.setAttribute("erreurs",erreurs1);
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// on récupère les données du modèle
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
As linhas 4–8 foram adicionadas para criar o modelo exigido pela página nas linhas 13–14.
Inicie o Tomcat, caso ainda não o tenha feito, e, em seguida, solicite os seguintes URLs:
![]() | ![]() |
![]() |
Recebemos as visualizações esperadas.
7.6. O controlador [ServletPersonne]
O controlador [ServletPersonne] da aplicação web [/personne3] irá tratar das seguintes ações:
Não. | pedido | origem | processamento |
1 | [GET /person3/hand] | URL introduzida pelo utilizador | - Enviar o [formulário] vazio |
2 | [POST /person3/main] com os parâmetros [txtName, txtAge, action=validateForm] enviado | clique no [Submit] 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 /person3/main] com os parâmetros [action=returnForm] hospedado | clique no [Voltar ao formulário] visualizações [resposta] e [erros]. | - Enviar a vista do [formulário] pré-preenchida com os valores introduzidos mais recentemente |
Temos, portanto, uma nova ação para tratar: [POST /person3/main] com o parâmetro enviado [action=returnForm]. Em vez da ação antiga [GET /person3/main?action=returnForm].
7.6.1. Estrutura do controlador
O esqueleto do controlador [ServletPersonne] é idêntico ao da versão anterior.
Novidades:
- Linha 11: A matriz [parameters] já não contém o parâmetro [urlController], que foi removido do ficheiro [web.xml].
Os métodos [init, doValidationFormulaire] permanecem inalterados. Os métodos [doGet, doInit, doRetourFormulaire] sofreram pequenas alterações.
7.6.2. O método [doGet]
O método [doGet] deve tratar a ação [POST /person3/main] com o parâmetro enviado [action=returnForm]:
- linhas 6-9: processamento da ação [POST /person3/main] com o parâmetro enviado [action=returnForm]
7.6.3. O método [doInit]
Este método trata do pedido n.º 1 [GET /person3/hand]. O seu código é o seguinte:
A alteração consiste no facto de a vista [form] apresentada na linha 8 já não ter o elemento [action] no seu modelo.
7.6.4. O método [doRetourFormulaire]
Este método processa o pedido n.º 1 [POST /person3/main] com [action=formSubmit] nos elementos enviados. O seu código é o seguinte:
A alteração consiste no facto de a vista [form] apresentada na linha 14 já não ter o elemento [action] no seu modelo.
7.7. Testes
Inicie ou reinicie o Tomcat após integrar o projeto Eclipse [personne-mvc-03] nele. Aceda ao URL [http://localhost:8080/personne3] e, em seguida, repita os testes apresentados como exemplo na secção 7.1.















