5. Applicazione Web MVC [person] – Versione 1
5.1. Le viste dell'applicazione
L'applicazione utilizza il modulo degli esempi precedenti. La prima pagina dell'applicazione è la seguente:

Chiameremo questa vista vista [form]. Se i dati inseriti sono corretti, vengono visualizzati in una vista che chiameremo [response]:

Se i dati inseriti non sono corretti, gli errori vengono visualizzati in una vista denominata [errori]:

5.2. Architettura dell'applicazione
L'applicazione web [person1] avrà la seguente architettura:

Si tratta di un'architettura monolivello: non sono presenti livelli [business] o [DAO], ma solo un livello [web]. [ServletPersonne] è il controller dell'applicazione che gestisce tutte le richieste dei client. Per rispondere a tali richieste, utilizza una delle tre viste [form, response, errors].
Dobbiamo determinare in che modo il controller [ServletPersonne] stabilisce l'azione da intraprendere al ricevimento di una richiesta dell'utente. Una richiesta del client è un flusso HTTP che varia a seconda che sia effettuata con un comando GET o POST.
Richiesta GET
In questo caso, il flusso HTTP si presenta come segue:
La riga 1 specifica l'URL richiesto, ad esempio:
Questo URL può essere utilizzato per specificare l'azione da eseguire. È possibile utilizzare vari metodi:
- Un parametro URL specifica l'azione, ad esempio [/app?action=add&id=4]. In questo caso, il parametro [action] indica al controller quale azione è stata richiesta.
- L'ultimo elemento dell'URL specifica l'azione, ad esempio [/app/add?id=4]. In questo caso, l'ultimo elemento dell'URL [/add] viene utilizzato dal controller per determinare l'azione che deve eseguire.
Sono possibili altre soluzioni. Le due menzionate sopra sono comuni.
Richiesta POST
In questo caso, il flusso HTTP è il seguente:
La riga 1 specifica l'URL richiesto, ad esempio:
Questo URL può essere utilizzato per specificare l'azione da eseguire, proprio come con GET. Nel caso di GET, il parametro [action] era incluso nell'URL. Ciò può valere anche in questo caso, come in:
Tuttavia, il parametro [action] può anche essere incluso nei parametri inviati (riga 15 sopra), come in:
Di seguito, useremo queste diverse tecniche per indicare al controller cosa fare:
- includere il parametro dell'azione nell'URL richiesto:
- Invia il parametro action:
- Utilizza l'ultimo elemento dell'URL come nome dell'azione:
5.3. Il progetto Eclipse
Per creare il progetto Eclipse [mvc-personne-01] per l'applicazione web [personne1], seguire la procedura descritta nella sezione 3.1.

Non manterremo il contesto predefinito [mvc-personne-01]. Sceglieremo [personne1] come mostrato di seguito:

Il risultato è il seguente:

Se desideri modificare il contesto dell'applicazione web, utilizza l'opzione [clic destro sul progetto -> Proprietà -> J2EE]:

Inserisci il nuovo contesto in [1].
Creeremo una sottocartella [vues] nella cartella [WEB-INF]: [clic destro su WEB-INF -> Nuovo -> Cartella]:
![]() | ![]() |
Il nuovo progetto ora appare così:

Una volta completato, il progetto avrà questo aspetto:

- Il controller [ServletPersonne] si trova nella cartella [src]
- Le pagine JSP relative alle viste [form, response, errors] si trovano nella cartella [WEB-INF/vues], il che impedisce all'utente di accedervi direttamente, come illustrato nell'esempio seguente:

Descriveremo ora i vari componenti dell'applicazione web [/personne1]. Il lettore è invitato a crearli man mano che procede nella lettura.
5.4. Configurazione dell'applicazione web [person1]
Il file web.xml per l'applicazione /person1 sarà il seguente:
<?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>
<!-- 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>
Cosa dice questo file di configurazione?
- righe 34–37: l'URL /main è gestito dal servlet denominato person
- righe 10-13: il servlet denominato "person" è un'istanza della classe [ServletPersonne]
- righe 14–19: definiscono un parametro di configurazione denominato [urlResponse]. Si tratta dell'URL della vista [response].
- Righe 20–25: definiscono un parametro di configurazione denominato [urlErrors]. Si tratta dell'URL della vista [errors].
- Righe 26–31: definiscono un parametro di configurazione denominato [urlForm]. Si tratta dell’URL della vista [form].
- Riga 40: [index.jsp] sarà la pagina iniziale dell'applicazione.
Gli URL delle pagine JSP per le viste [form, response, errors] sono definiti ciascuno da un parametro di configurazione. Ciò consente di spostarli senza dover ricompilare l'applicazione.
Quando l'utente richiede l'URL [/person1], il file [index.jsp] invierà la risposta (file della home page, riga 40). Questo file si trova nella directory principale della cartella [WebContent]:

Il suo contenuto è il seguente:
<%@ 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");
%>
La pagina [index.jsp] reindirizza semplicemente il client all'URL [/person1/main]. Pertanto, quando il browser richiede l'URL [/person1], [index.jsp] gli invia la seguente risposta HTTP:
- Riga 1: risposta HTTP/1.1 per indicare al server di reindirizzare a un altro URL
- Riga 4: L'URL a cui il browser deve reindirizzare
Dopo questa risposta, il browser richiederà l'URL [/person1/main] come indicato (riga 4). Il file [web.xml] dell'applicazione [/person1] specifica che questa richiesta sarà gestita dal controller [ServletPersonne] (righe 35–36).
5.5. Il codice della vista
Iniziamo a scrivere l'applicazione web creando le sue viste. Queste aiutano a definire le esigenze dell'utente in termini di interfaccia grafica e possono essere testate senza il controller.
5.5.1. La vista [form]
Questa vista è per il modulo utilizzato per inserire nome ed età:

Tipo HTML | nome | ruolo | |
<input type="text"> | txtNome | Inserisci nome | |
<input type="text"> | txtEtà | Inserisci l'età | |
<input type="submit"> | Invia i valori inseriti al server all'URL /person1/main | ||
<input type="reset"> | per ripristinare la pagina allo stato in cui è stata inizialmente ricevuta dal browser | ||
<input type="button"> | per cancellare il contenuto dei campi di immissione [1] e [2] |
È generato dalla pagina JSP [formulaire.jsp]. Il suo modello è composto dai seguenti elementi:
- [name]: un nome (String) presente negli attributi di sessione associati alla chiave "name"
- [age]: un'età (String) presente negli attributi di sessione associati alla chiave "age"
La vista [form] si ottiene quando l'utente richiede l'URL [/person1/main], ovvero l'URL del controller [ServletPersonne]. Il codice della pagina JSP [formulaire.jsp] che genera la vista [form] è il seguente:
<%@ 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");
%>
<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>
- righe 6-7: La pagina JSP inizia recuperando gli elementi [name, age] del proprio modello dalla richiesta. Nel normale funzionamento dell'applicazione, il controller [ServletPersonne] costruirà questo modello.
- righe 18-38: la pagina JSP genera un modulo HTML (tag <form>)
- riga 18: il tag <form> non presenta l'attributo action per specificare l'URL che elaborerà i valori inviati tramite il pulsante [Submit] (riga 32). I valori del modulo verranno quindi inviati all'URL da cui è stato ottenuto il modulo, ovvero l'URL del controller [ServletPersonne]. Pertanto, questo controller viene utilizzato sia per generare il modulo vuoto inizialmente richiesto da una richiesta GET, sia per elaborare i dati inseriti che gli verranno inviati tramite il pulsante [Submit].
- I valori inviati sono quelli dei campi HTML [txtName] (riga 22), [txtAge] (riga 26) e [action] (riga 37). Quest'ultimo parametro consentirà al controller di sapere cosa deve fare.
- Quando il modulo viene visualizzato per la prima volta, i campi di immissione [txtName] e [txtAge] vengono inizializzati rispettivamente con le variabili [name] (riga 22) e [age] (riga 26). Queste variabili ottengono i loro valori dagli attributi della richiesta (righe 6–7), che, come è noto, vengono inizializzati dal servlet. È quindi il servlet che imposta il contenuto iniziale dei campi di immissione del modulo.
- Riga 33: il pulsante [Reset] di tipo [reset] riporta il modulo allo stato in cui si trovava quando il browser lo ha ricevuto.
- Riga 34: il pulsante [Clear] di tipo [reset] attualmente non ha alcuna funzione.
D'ora in poi, faremo riferimento a questa vista come vista [form(name, age)] quando vorremo specificare sia il nome della vista che il suo modello. Inoltre, si noti che quando l'utente fa clic sul pulsante [Submit], i parametri [txtName, txtAge] vengono inviati all'URL [/person1/main].
5.5.2. La vista [response]
Questa vista visualizza i valori inseriti nel modulo quando sono validi:

È generata dalla pagina JSP [reponse.jsp]. Il suo modello è costituito dai seguenti elementi:
- [name]: un nome (String) presente negli attributi di sessione, associato alla chiave "name"
- [age]: un'età (String) che si troverà negli attributi di sessione, associata alla chiave "age"
Il codice della pagina JSP [reponse.jsp] è il seguente:
<%@ 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");
%>
<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>
- Righe 6-7: La pagina JSP inizia recuperando gli elementi [name, age] del proprio modello dalla richiesta. Durante il normale funzionamento dell'applicazione, il controller [ServletPersonne] costruirà questo modello.
- Gli elementi del modello [name, age] vengono quindi visualizzati alle righe 20 e 24
Successivamente, ci riferiamo a questa vista come alla vista [response(name, age)].
5.5.3. La vista [errors]
Questa vista segnala gli errori di immissione nel formato:

Viene generata dalla pagina JSP [errors.jsp]. Il suo modello è costituito dai seguenti elementi:
- [errors]: un elenco (ArrayList) di messaggi di errore che si trovano negli attributi della richiesta, associati alla chiave "errors"
Il codice della pagina JSP [errors.jsp] è il seguente:
<%@ 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");
%>
<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>
</body>
</html>
- riga 8: la pagina JSP inizia recuperando l'elemento [errors] dal proprio modello nella richiesta. Questo elemento rappresenta un oggetto ArrayList contenente elementi String. Questi elementi sono messaggi di errore. Durante il normale funzionamento dell'applicazione, il controller [ServletPersonne] costruirà questo modello.
- Righe 18–22: visualizzano l'elenco dei messaggi di errore. Per farlo, dobbiamo scrivere codice Java all'interno del corpo HTML della pagina. Dovremmo sempre cercare di ridurlo al minimo per evitare di ingombrare il codice HTML. Vedremo in seguito che esistono soluzioni per ridurre la quantità di codice Java nelle pagine JSP.
- Riga 4: Notare il tag import per i pacchetti richiesti dalla pagina JSP
Ci riferiremo a questa vista come alla vista [errors(errors)].
5.6. Test delle viste
È possibile testare la validità delle pagine JSP senza aver ancora scritto il controller. Per farlo, devono essere soddisfatte due condizioni:
- È necessario poterle richiedere direttamente dall'applicazione senza passare attraverso il controller
- la pagina JSP deve inizializzare il modello stesso, che normalmente verrebbe costruito dal controller
Per eseguire questi test, duplichiamo le pagine JSP delle viste nella cartella [/WebContent/JSP] del progetto Eclipse:

Quindi, nella cartella JSP, le pagine vengono modificate come segue:
[form.jsp]:
...
<%
// -- test : on crée le modèle de la page
request.setAttribute("nom","tintin");
request.setAttribute("age","30");
%>
<%
// on récupère les données du modèle
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
...
Le righe 3–7 sono state aggiunte per creare il modello richiesto dalle righe 11–12.
[reponse.jsp]:
...
<%
// -- test : on crée le modèle de la page
request.setAttribute("nom","milou");
request.setAttribute("age","10");
%>
<%
// on récupère les données du modèle
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
<html>
<head>
...
Le righe 3–7 sono state aggiunte per creare il modello richiesto dalla pagina nelle righe 11–12.
[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);
%>
<%
// on récupère les données du modèle
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
<html>
<head>
...
Le righe 3–9 sono state aggiunte per creare il modello richiesto dalla riga 13.
Avvia Tomcat se non l'hai già fatto, quindi richiedi i seguenti URL:
![]() | ![]() |
![]() |
Otteniamo le visualizzazioni previste. Ora che abbiamo una ragionevole fiducia nelle pagine JSP dell'applicazione, possiamo passare alla scrittura del suo controller [ServletPersonne].
5.7. Il controller [ServletPersonne]
Non resta che scrivere il cuore della nostra applicazione web: il controller. Il suo ruolo è quello di:
- recuperare la richiesta del client,
- elaborare l'azione richiesta dal cliente,
- inviare la vista appropriata in risposta.
Il controller [ServletPersonne] gestirà le seguenti azioni:
richiesta | richiesta | origine | elaborazione |
1 | [GET /person1/hand] | URL inserito dall'utente | - invia la vista [form] vuota |
2 | [POST /person1/hand] con i parametri [txtName, txtAge, action] | fare clic sul pulsante [Invia] nel [form] | - controlla i valori dei parametri [txtName, txtAge] - se sono errati, inviare la vista [errors(errors)] - se sono corretti, invia la vista [response(name,age)] |
L'applicazione si avvia quando l'utente richiede l'URL [/person1/main]. Secondo il file [web.xml] dell'applicazione (vedi Sezione 5.4), questa richiesta viene gestita da un'istanza della classe ServletPersonne, che descriveremo ora.
5.7.1. Struttura del controller
Il codice del controller [ServletPersonne] è il seguente:
- righe 20–22: il metodo [init] viene eseguito al primo caricamento del servlet
- righe 25-28: il metodo [doGet] chiamato dal server web quando viene effettuata una richiesta GET all'applicazione
- righe 42-46: il metodo [doPost] chiamato dal server web quando viene effettuata una richiesta POST all'applicazione. Come mostrato, anche questa sarà gestita dal metodo [doGet] (riga 45).
- righe 31-33: il metodo [doInit] gestisce l'azione n. 1 [GET /person1/main]
- Righe 36–39: il metodo [doValidationFormulaire] gestisce l'azione n. 2 [POST /person1/main] con i parametri inviati [txtName, txtAge, action].
Descriveremo ora i vari metodi del controller
5.7.2. Inizializzazione del controller
Quando la classe del controller viene caricata dal contenitore servlet, viene eseguito il suo metodo [init]. Ciò avviene una sola volta. Una volta caricato in memoria, il controller vi rimane ed elabora le richieste provenienti da diversi client. Ogni client è gestito da un thread di esecuzione separato, quindi i metodi del controller vengono eseguiti simultaneamente da thread diversi. Si noti che, per questo motivo, il controller non deve avere alcun campo che i suoi metodi possano modificare. I suoi campi devono essere di sola lettura. Essi vengono inizializzati dal metodo [init], che è la sua funzione principale. Questo metodo ha la caratteristica unica di essere eseguito una sola volta da un singolo thread. Pertanto, non ci sono problemi di accesso concorrente ai campi del controller all'interno di questo metodo. Lo scopo del metodo [init] è quello di inizializzare gli oggetti richiesti dall'applicazione web, che saranno condivisi in modalità di sola lettura da tutti i thread dei client. Questi oggetti condivisi possono essere collocati in due posizioni:
- i campi privati del controller
- il contesto di esecuzione dell'applicazione (ServletContext)
Il codice per il metodo [init] del controller [ServletPersonne] è il seguente:
- riga 16: viene recuperata la configurazione dell'applicazione web, ovvero il contenuto del file [web.xml]
- righe 19–29: vengono recuperati i parametri di inizializzazione del servlet, i cui nomi sono definiti nell'array [parameters] alla riga 9
- riga 21: viene recuperato il valore del parametro
- riga 25: se il parametro manca, l'errore viene aggiunto all'elenco degli errori [initializationErrors], inizialmente vuoto (riga 8).
- Riga 28: se il parametro è presente, viene memorizzato insieme al suo valore nel dizionario [params] inizialmente vuoto (riga 10).
- righe 31–35: il parametro [urlErrors] deve essere presente perché specifica l'URL della vista [errors] in grado di visualizzare eventuali errori di inizializzazione. Se non esiste, l'applicazione viene terminata generando un'eccezione [ServletException] (riga 33).
5.7.3. Il metodo [doGet]
Il metodo [doGet] gestisce sia le richieste GET che POST al servlet, poiché il metodo [doPost] reindirizza al metodo [doGet]. Il suo codice è il seguente:
- Righe 18–25: Verifichiamo che l'elenco degli errori di inizializzazione sia vuoto. Se non lo è, visualizziamo la vista [errors(initializationErrors)], che riporterà gli errori.
Per comprendere questo codice, è necessario richiamare il modello di vista [errors]:
<%
// on récupère les données du modèle
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
La vista [errori] si aspetta una chiave denominata "errori" nella richiesta. Il controller crea questa chiave alla riga 20.
- Riga 28: recuperiamo il metodo [get] o [post] che il client ha utilizzato per effettuare la richiesta
- Riga 30: recuperiamo il valore del parametro [action] dalla richiesta. Ricordiamo che nella nostra applicazione, solo la richiesta n. 2 [POST /person1/main] ha il parametro [action]. In questa richiesta, ha il valore [validationFormulaire].
- Righe 31–34: Se il parametro [action] non è presente, gli assegniamo il valore "init". Questo sarà il caso della richiesta iniziale n. 1 [GET /person1/main].
- Righe 36–40: Elaborazione della richiesta n. 1 [GET /person1/main].
- Righe 41–45: Elaborazione della richiesta n. 2 [POST /person1/main].
- Riga 47: Se nessuno dei due casi precedenti si applica, procediamo come se fossimo nel caso n. 1
5.7.4. Il metodo [doInit]
Questo metodo gestisce la richiesta n. 1 [GET /person1/main]. Per questa richiesta, deve restituire la vista vuota [form(name, age)]. Il suo codice è il seguente:
- righe 18-19: viene visualizzata la vista [form]. Ricordiamo il modello previsto da questa vista:
<%
// on récupère les données du modèle
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
- Righe 16-17: Il modello [name, age] della vista [form] viene inizializzato con stringhe vuote.
5.7.5. Il metodo [doValidationForm]
Questo metodo elabora la richiesta n. 2 [POST /person1/main], in cui i parametri inviati sono [action, txtName, txtAge]. Il suo codice è il seguente:
- righe 16-17: i valori dei parametri "txtNom" e "txtAge" vengono recuperati dalla richiesta del client.
- righe 19-26: viene verificata la validità di questi due parametri
- righe 28-33: se uno dei due parametri è errato, viene visualizzata la vista [errors(callErrors)]. Ricordiamo il template per questa vista:
<%
// on récupère les données du modèle
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
%>
- righe 35-38: se i due parametri recuperati "txtNom" e "txtAge" hanno valori validi, viene visualizzata la vista [response(name, age)]. Ricordiamo il template per la vista [response]:
<%
// on récupère les données du modèle
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
%>
5.8. Test
Includiamo il progetto [mvc-personne-01] nelle applicazioni Tomcat seguendo la procedura descritta nella sezione 3.3:

Avviamo Tomcat. Una volta fatto ciò, possiamo riprendere i test mostrati come esempi nella Sezione 5.1. Possiamo aggiungere altri test. Ad esempio, possiamo rimuovere uno dei parametri di configurazione urlXXX da web.xml e vedere il risultato. Come mostrato di seguito, uno dei parametri è commentato in [web.xml]:
<!--
<init-param>
<param-name>urlFormulaire</param-name>
<param-value>
/WEB-INF/vues/formulaire.jsp
</param-value>
</init-param>
-->
Avviamo o riavviamo Tomcat e inviamo una richiesta all'URL [http://localhost:8080/personne1/main]. Otteniamo la seguente risposta:





