5. Aplicativo web MVC [personne] – versão 1
5.1. As visualizações da aplicação
A aplicação utiliza o formulário empregado nos exemplos anteriores. A primeira página da aplicação é a seguinte:

Chamaremos essa visualização de [formulaire]. Se forem feitas entradas corretas, elas serão exibidas em uma visualização que será chamada de [réponse]:

Se as entradas estiverem incorretas, os erros serão sinalizados em uma visualização chamada [erreurs]:

5.2. Arquitetura do aplicativo
A aplicação web [personne1] terá a seguinte arquitetura:

Essa arquitetura é de camada única: não há camadas [métier] ou [dao], apenas uma camada [web]. [ServletPersonne] é o controlador da aplicação que processa todas as solicitações dos clientes. Para responder a elas, ele utiliza uma das três visualizações [formulaire, réponse, erreurs].
Precisamos determinar como o controlador [ServletPersonne] decide qual ação deve realizar ao receber uma solicitação de um usuário. Uma solicitação do cliente é um fluxo HTTP que varia dependendo se é feita com um comando GET ou POST.
Solicitação GET
Nesse caso, o fluxo HTTP tem a seguinte aparência:
A linha 1 especifica a URL solicitada, por exemplo:
É possível usar essa URL para especificar a ação a ser realizada. Podem ser utilizados diversos métodos:
- um parâmetro da URL especifica a ação, por exemplo, [/appli?action=ajouter&id=4]. Aqui, o parâmetro [action] indica ao controlador a ação que lhe é solicitada.
- o último elemento da URL especifica a ação, por exemplo, [/appli/ajouter?id=4]. Aqui, o último elemento da URL [/ajouter] é usado pelo controlador para determinar a ação que ele deve realizar.
Outras soluções são possíveis. As duas anteriores são comuns.
Solicitação POST
Nesse caso, o fluxo HTTP fica assim:
A linha 1 especifica a URL solicitada, por exemplo:
É possível usar essa URL para especificar a ação a ser realizada, como no caso do GET. No caso do GET, o parâmetro [action] estava integrado no URL. Isso também pode ocorrer aqui, como em:
Mas o parâmetro [action] também pode estar incluído nos parâmetros enviados (linha 15 acima), como em:
A seguir, utilizaremos essas diferentes técnicas para indicar ao controlador o que ele deve fazer:
- incluir o parâmetro action na URL solicitada:
- enviar o parâmetro action:
- utilizar o último elemento da URL como nome da ação:
5.3. O projeto Eclipse
Para criar o projeto Eclipse [mvc-personne-01] da aplicação web [personne1], siga os passos descritos no parágrafo 3.1.

Não manteremos o contexto [mvc-personne-01] proposto por padrão. Escolheremos [personne1], conforme indicado abaixo:

O resultado obtido é o seguinte:

Caso, por acaso, queiramos alterar o contexto do aplicativo web, utilizaremos a opção [clic droit sur projet -> Properties -> J2EE]:

O novo contexto será indicado em [1].
Vamos criar uma subpasta [vues] na pasta [WEB-INF]: [clic droit sur WEB-INF -> New -> Folder]:
![]() | ![]() |
O novo projeto agora é este:

Quando estiver concluído, o projeto ficará assim:

- O controlador [ServletPersonne] está na pasta [src]
- as páginas JSP das visualizações [formulaire, réponse, erreurs] estão na pasta [WEB-INF/vues], o que impede que o usuário as acesse diretamente, conforme mostra o exemplo abaixo:

Descreveremos agora os diferentes componentes do aplicativo web [/personne1]. O leitor é convidado a criá-los à medida que avança na leitura.
5.4. Configuração da aplicação web [personne1]
O arquivo web.xml da aplicação /pessoa1 será 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-01</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>
</servlet>
<!-- Mapeamento ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
<!-- arquivos de página inicial -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
O que diz esse arquivo de configuração?
- linhas 34-37: o URL /main é processado pelo servlet chamado pessoa
- linhas 10-13: o servlet chamado “pessoa” é uma instância da classe [ServletPersonne]
- linhas 14-19: definem um parâmetro de configuração chamado [urlReponse]. Trata-se da URL da visualização [réponse].
- linhas 20-25: definem um parâmetro de configuração chamado [urlErreurs]. Trata-se da URL da visualização [erreurs].
- linhas 26-31: definem um parâmetro de configuração chamado [urlFormulaire]. Essa é a URL da visualização [formulaire].
- linha 40: [index.jsp] será a página inicial do aplicativo.
As URLs das páginas JSP das visualizações [formulaire, réponse, erreurs] são definidas, cada uma, por um parâmetro de configuração. Isso permite movê-las sem precisar recompilar o aplicativo.
Quando o usuário acessar a URL [/personne1], será o arquivo [index.jsp] que enviará a resposta (arquivo inicial, linha 40). Esse arquivo está na raiz da pasta [WebContent]:

Seu conteúdo é o 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">
<%
response.sendRedirect("/personne1/main");
%>
A página [index.jsp] limita-se a redirecionar o cliente para a URL [/personne1/main]. Assim, quando o navegador solicita a URL [/personne1], [index.jsp] envia a seguinte resposta:
- linha 1: resposta HTTP/1.1 para indicar ao servidor que se redirecione para outro URL
- linha 4: o URL para o qual o navegador deve ser redirecionado
Após essa resposta, o navegador solicitará, portanto, a URL [/personne1/main], conforme solicitado (linha 4). O arquivo [web.xml] do aplicativo [/personne1] indica que essa solicitação será processada pelo controlador [ServletPersonne] (linhas 35-36).
5.5. O código das visualizações
Começamos a desenvolvimento da aplicação web pela criação de suas visualizações. Elas permitem identificar as necessidades do usuário em termos de interface gráfica e podem ser testadas sem a presença do controlador.
5.5.1. A visualização [formulaire]
Esta vista corresponde ao formulário de preenchimento do nome e da idade:

tipo HTML | nome | função | |
<input type="text"> | txtNom | inserção do nome | |
<input type="text"> | txtAge | inserção da idade | |
<input type="submit"> | envio dos valores inseridos ao servidor na URL /pessoa1/main | ||
<input type="reset"> | para restaurar a página ao estado em que foi recebida inicialmente pelo navegador | ||
<input type="button"> | para limpar o conteúdo dos campos de entrada [1] e [2] |
Ela é gerada pela página JSP [formulaire.jsp]. Seu modelo é composto pelos seguintes elementos:
- [nom]: um nome (String) encontrado nos atributos de sessão associados à chave “nom”
- [age]: uma idade (String) encontrada nos atributos de sessão associados à chave “idade”
A visualização [formulaire] é obtida quando o usuário solicita a URL [/personne1/main], c.a.d. A URL do controlador [ServletPersonne]. O código da página JSP [formulaire.jsp], que gera a visualização [formulaire], é o 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">
<%
// recuperamos os dados do modelo
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
<title>Personne - formulaire</title>
</head>
<body>
<center>
<h2>Personne - formulaire</h2>
<hr>
<form 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="Envoyer"></td>
<td><input type="reset" value="Rétablir"></td>
<td><input type="button" value="Effacer"></td>
</tr>
</table>
<input type="hidden" name="action" value="validationFormulaire">
</form>
</center>
</body>
</html>
- linhas 6-7: a página JSP começa recuperando, na solicitação [request], os elementos [nom, age] de seu modelo. No funcionamento normal do aplicativo, será o controlador [ServletPersonne] que construirá esse modelo.
- linhas 18-38: a página JSP irá gerar um formulário HTML (tag <form>)
- linha 18: a tag <form> não possui o atributo action para indicar a URL que deverá processar os valores enviados pelo botão [Envoyer] do tipo submit (linha 32). Os valores do formulário serão, então, enviados para a URL a partir da qual o formulário foi obtido, ou seja, a URL do controlador [ServletPersonne]. Assim, ele é utilizado tanto para gerar o formulário vazio solicitado inicialmente por um GET quanto para processar os dados inseridos que serão enviados a ele por meio do botão [Envoyer].
- Os valores enviados são os dos campos HTML, [txtNom] (linha 22), [txtAge] (linha 26) e [action] (linha 37). Esse último parâmetro permitirá que o controlador saiba o que deve fazer.
- Na exibição inicial do formulário, os campos de entrada [txtNom, txtAge] são inicializados, respectivamente, com as variáveis [nom] (linha 22) e [age] (linha 26). Essas variáveis obtêm os valores de seus atributos da consulta (linhas 6-7), atributos que sabemos serem inicializados pelo servlet. Portanto, é este último que define o conteúdo inicial dos campos de entrada do formulário.
- linha 33: o botão [Rétablir], do tipo [reset], permite restaurar o formulário ao estado em que se encontrava quando foi recebido pelo navegador.
- linha 34: o botão [Effacer], do tipo [reset], não tem, por enquanto, nenhuma função.
Posteriormente, chamaremos essa visualização de visualização [formulaire(nom, age)] quando quisermos especificar tanto o nome da visualização quanto seu modelo. Além disso, vale lembrar que, quando o usuário clica no botão [Envoyer], os parâmetros [txtNom, txtAge] são enviados para a URL [/personne1/main].
5.5.2. A visualização [reponse]
Essa visualização exibe os valores inseridos no formulário quando estes são válidos:

Ela é gerada pela página JSP [reponse.jsp]. Seu modelo é composto pelos seguintes elementos:
- [nom]: um nome (String) que será encontrado nos atributos da sessão, associado à chave “nom”
- [age]: uma idade (String) que será encontrada nos atributos da sessão, associada à chave “idade”
O código da página JSP [reponse.jsp] é o 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">
<%
// recuperando os dados do modelo
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<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>
</body>
</html>
- linhas 6-7: a página JSP começa recuperando, na solicitação [request], os elementos [nom, age] de seu modelo. No funcionamento normal do aplicativo, será o controlador [ServletPersonne] que construirá esse modelo.
- Os elementos [nom, age] do modelo são, em seguida, exibidos nas linhas 20 e 24
Posteriormente, chamamos essa visualização de visualização [réponse(nom, age)].
5.5.3. A visualização [erreurs]
Essa visualização sinaliza os erros de preenchimento no formulário:

Ela é gerada pela página JSP [erreurs.jsp]. Seu modelo é composto pelos seguintes elementos:
- [erreurs]: uma lista (ArrayList) de mensagens de erro que será encontrada nos atributos da consulta, associada à chave “erros”
O código da página JSP [erreurs.jsp] é o 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" %>
<%
// recuperando os dados do modelo
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
<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");
}//para
%>
</ul>
</body>
</html>
- linha 8: a página JSP começa recuperando, na solicitação [request], o elemento [erreurs] de seu modelo. Esse elemento representa um objeto do tipo ArrayList, composto por elementos do tipo String. Esses elementos são mensagens de erro. No funcionamento normal do aplicativo, será o controlador [ServletPersonne] que construirá esse modelo.
- linhas 18-22: exibem a lista de mensagens de erro. Para isso, é necessário escrever código Java no corpo HTML da página. Deve-se sempre procurar reduzir esse código ao mínimo para não sobrecarregar o código HTML. Veremos posteriormente que existem soluções que permitem reduzir a quantidade de código Java nas páginas JSP.
- linha 4: observe a tag de importação dos pacotes necessários para a página JSP
Posteriormente, chamamos essa visualização de visualização [erreurs(erreurs)].
5.6. Testes das visualizações
É possível testar a validade das páginas JSP sem ter escrito o controlador. Para isso, são necessárias duas condições:
- é preciso poder solicitá-las diretamente à aplicação, sem passar pelo controlador
- é necessário que a página JSP inicialize por conta própria o modelo que, normalmente, seria construído pelo controlador
Para realizar esses testes, duplicamos as páginas JSP das visualizações na pasta [/WebContent/JSP] do projeto Eclipse:

Em seguida, na pasta JSP, as páginas são modificadas da seguinte maneira:
[formulaire.jsp]:
...
<%
// -- teste: cria-se o modelo da página
request.setAttribute("nom","tintin");
request.setAttribute("age","30");
%>
<%
// recuperam-se os dados do modelo
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
...
As linhas 3 a 7 foram adicionadas para criar o modelo necessário para a página nas linhas 11 e 12.
[reponse.jsp]:
...
<%
// -- teste: cria-se o modelo da página
request.setAttribute("nom","milou");
request.setAttribute("age","10");
%>
<%
// recuperamos os dados do modelo
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
...
As linhas 3 a 7 foram adicionadas para criar o modelo necessário para a página das linhas 11 e 12.
[erreurs.jsp]:
...
<%
// -- teste: criamos o modelo da página
ArrayList<String> erreurs1=new ArrayList<String>();
erreurs1.add("erreur1");
erreurs1.add("erreur2");
request.setAttribute("erreurs",erreurs1);
%>
<%
// recuperam-se os dados do modelo
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
<html>
<head>
...
As linhas 3 a 9 foram adicionadas para criar o modelo necessário para a página da linha 13.
Inicie o Tomcat, caso ainda não tenha feito isso, e, em seguida, acesse as seguintes URLs:
![]() | ![]() |
![]() |
Recebemos as visualizações esperadas. Agora que temos uma confiança razoável nas páginas JSP do aplicativo, podemos passar à criação de seu controlador [ServletPersonne].
5.7. O controlador [ServletPersonne]
Resta escrever o núcleo do nosso aplicativo web: o controlador. Sua função consiste em:
- receber a solicitação do cliente,
- processar a ação solicitada pelo cliente,
- enviar a visualização apropriada como resposta.
O controlador [ServletPersonne] processará as seguintes ações:
n.º | solicitação | origem | processamento |
1 | [GET /personne1/main] | URL digitada pelo usuário | - enviar a visualização [formulaire] vazia |
2 | [POST /personne1/main] com parâmetros [txtNom, txtAge, ação] publicados | ao clicar no botão [Envoyer] da visualização [formulaire] | - verificar os valores dos parâmetros [txtNom, txtAge] - se estiverem incorretos, enviar a visualização [erreurs(erreurs)] - se estiverem corretos, enviar a visualização [reponse(nom,age)] |
O aplicativo é iniciado quando o usuário solicita a URL [/personne1/main]. De acordo com o arquivo [web.xml] do aplicativo (ver parágrafo 5.4), essa solicitação é processada por uma instância do tipo ServletPersonne, que descreveremos a seguir.
5.7.1. Estrutura do controlador
O código do controlador [ServletPersonne] é o seguinte:
- linhas 20-22: o método [init] executado no carregamento inicial do servlet
- linhas 25-28: o método [doGet] chamado pelo servidor web quando uma solicitação do tipo GET é feita ao aplicativo
- linhas 42-46: o método [doPost] chamado pelo servidor web quando uma solicitação do tipo POST é feita à aplicação. Conforme mostrado, essa solicitação também será processada pelo método [doGet] (linha 45).
- linhas 31-33: o método [doInit] processa a ação nº 1 [GET /personne1/main]
- linhas 36-39: o método [doValidationFormulaire] processa a ação nº 2 [POST /personne1/main] com os parâmetros enviados por [txtNom, txtAge, action].
Descreveremos agora os diferentes métodos do controlador
5.7.2. Inicialização do controlador
Quando a classe do controlador é carregada pelo contêiner de servlets, seu método [init] é executado. Isso ocorrerá apenas uma vez. Uma vez carregado na memória, o controlador permanecerá nela e processará as solicitações dos diferentes clientes. Cada cliente é alocado a um thread de execução e, assim, os métodos do controlador são executados simultaneamente por diferentes threads. Vale lembrar que, por esse motivo, o controlador não deve possuir campos que possam ser modificados por seus métodos. Seus campos devem ser somente de leitura. Eles são inicializados pelo método [init], cuja função principal é justamente essa. Esse método tem, de fato, a particularidade de ser executado uma única vez por um único thread. Portanto, não há problemas de acesso simultâneo aos campos do controlador nesse método. O método [init] tem como objetivo inicializar os objetos necessários para a aplicação web, que serão compartilhados em modo somente leitura por todas as threads clientes. Esses objetos compartilhados podem ser colocados em dois locais:
- nos campos privados do controlador
- o contexto de execução da aplicação (ServletContext)
O código do método [init] do controlador [ServletPersonne] é o seguinte:
- linha 16: recupera-se a configuração da aplicação web, c.a.d. O conteúdo do arquivo [web.xml]
- linhas 19-29: recuperam-se os parâmetros de inicialização do servlet, cujos nomes estão definidos na tabela [paramètres] da linha 9
- linha 21: o valor do parâmetro é recuperado
- linha 25: se o parâmetro estiver ausente, o erro é adicionado à lista de erros [erreursInitialisation], inicialmente vazia (linha 8).
- linha 28: se o parâmetro estiver presente, ele é armazenado com seu valor no dicionário [params], inicialmente vazio (linha 10).
- linhas 31-35: o parâmetro [urlErreurs] deve estar obrigatoriamente presente, pois indica a URL da visualização [erreurs] capaz de exibir eventuais erros de inicialização. Se ele não existir, a aplicação é interrompida com a execução de um [ServletException] (linha 33).
5.7.3. O método [doGet]
O método [doGet] processa tanto as solicitações GET quanto as POST no servlet, uma vez que o método [doPost] redireciona para o método [doGet]. Seu código é o seguinte:
- linhas 18-25: verifica-se se a lista de erros de inicialização está vazia. Caso contrário, exibe-se a vista [erreurs(erreursInitialisation)], que sinalizará o(s) erro(s).
Para entender esse código, é preciso lembrar o modelo da visualização [erreurs]:
<%
// recuperação dos dados do modelo
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
A visualização [erreurs] espera um elemento-chave “erros” na solicitação. O controlador cria esse elemento na linha 20.
- linha 28: recupera-se o método [get] ou [post] que o cliente utilizou para fazer sua consulta
- linha 30: recupera-se o valor do parâmetro [action] da solicitação. Vale lembrar que, em nosso aplicativo, apenas a solicitação nº 2, [POST /personne1/main], possui o parâmetro [action]. Nessa solicitação, ele tem o valor [validationFormulaire].
- linhas 31-34: se o parâmetro [action] não estiver presente, atribui-se a ele o valor “init”. Esse será o caso na solicitação inicial nº 1, [GET /personne1/main].
- linhas 36-40: processamento da solicitação nº 1 [GET /personne1/main].
- linhas 41-45: processamento da solicitação nº 2 [POST /personne1/main].
- linha 47: se não estivermos em nenhum dos dois casos anteriores, procedemos como se estivéssemos no caso nº 1
5.7.4. O método [doInit]
Este método processa a solicitação nº 1 [GET /personne1/main]. Nessa solicitação, ele deve enviar a visualização [formulaire(nom,age)] vazia. Seu código é o seguinte:
- linhas 18-19: a visualização [formulaire] é exibida. Vale lembrar o modelo esperado por essa visualização:
<%
// recuperam-se os dados do modelo
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
- linhas 16-17: o modelo [nom,age] da visualização [formulaire] é inicializado com strings vazias.
5.7.5. O método [doValidationFormulaire]
Este método processa a solicitação nº 2 [POST /personne1/main], na qual os parâmetros enviados são [action, txtNom, txtAge]. Seu código é o seguinte:
- linhas 16-17: recuperam-se da solicitação do cliente os valores dos parâmetros “txtNom” e “txtAge”.
- linhas 19-26: verifica-se a validade desses dois parâmetros
- linhas 28-33: se algum dos parâmetros estiver incorreto, exibe-se a visualização [erreurs(erreursAppel)]. Vale lembrar o modelo dessa visualização:
<%
// recuperando os dados do modelo
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
- linhas 35-38: se os dois parâmetros “txtNom” e “txtAge” recuperados tiverem valores válidos, exibe-se a visualização [reponse(nom,age)]. É preciso lembrar o modelo da visualização [reponse]:
<%
// recuperando os dados do modelo
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
5.8. Tests
Vamos incluir o projeto [mvc-personne-01] nas aplicações do Tomcat, seguindo o procedimento descrito no parágrafo 3.3:

Inicie o Tomcat. Feito isso, será possível retomar os testes apresentados como exemplo no parágrafo 5.1. Também será possível adicionar outros testes. Por exemplo, podemos remover um dos parâmetros de configuração urlXXX do web.xml e observar o resultado. Assim, conforme mostrado abaixo, um dos parâmetros foi colocado entre comentários no [web.xml]:
<!--
<init-param>
<param-name>urlFormulaire</param-name>
<param-value>
/WEB-INF/vues/formulaire.jsp
</param-value>
</init-param>
-->
Inicializamos/reinicializamos o Tomcat e acessamos a URL [http://localhost:8080/personne1/main]. Obtemos a seguinte resposta:





