7. Aplicación web MVC [personne] – versión 3
Lecturas recomendadas en [ref1]: capítulo 9
7.1. Introduction
Nos proponemos agregar código JavaScript a las páginas HTML enviadas al navegador. Es este último el que ejecuta el código JavaScript incrustado en la página que muestra. Esta tecnología es independiente de la que utiliza el servidor web para generar el documento HTML (Java/servlets/JSP, ASP.NET, ASP, PHP, Perl, Python, ...).
[formulaire.jsp]
La vista resultante de esta página tendrá el siguiente aspecto:

Los botones cuyo texto aparece en un recuadro utilizan código JavaScript integrado en la página HTML:
Texto | Tipo HTML | Función |
<submit> | desempeña la función del botón [Envoyer] de las versiones anteriores: envía los valores ingresados al controlador | |
<button> | nuevo botón: verifica localmente la validez de los datos ingresados antes de enviarlos al controlador | |
<reset> | restablece el formulario al estado en el que lo recibió inicialmente el navegador | |
<button> | borra el contenido de los dos campos de entrada |
A continuación se muestra un ejemplo de uso de los botones [Envoyer] y [Effacer]:
![]() | ![]() |
![]() | ![]() |
También utilizaremos código JavaScript para gestionar el enlace [Retour au formulaire] de las vistas [erreurs] y [réponse]. Tomemos como ejemplo la vista [réponse]:
![]() | 1 ![]() |
La diferencia está en la URL que se muestra en [1]. En la versión anterior, esta era:
Aquí, la acción ya no forma parte de la URL porque se enviará mediante un POST en lugar de un GET. Esta modificación hará que la única URL que muestre el navegador sea [http://localhost:8080/personne3/main], independientemente de la acción solicitada.
7.2. El proyecto de Eclipse
Para crear el proyecto Eclipse [mvc-personne-03] de la aplicación web [/personne3], se duplicará el proyecto [mvc-personne-02] siguiendo el procedimiento descrito en el párrafo 6.2, página 78.
![]() | ![]() |
7.3. Configuración de la aplicación web [personne3]
El archivo web.xml de la aplicación /persona3 es el siguiente:
<?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>
<!-- Mapeo ServletPersonne-->
<servlet-mapping>
<servlet-name>personne</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
<!-- archivos de inicio -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Este archivo es idéntico al de la versión anterior, salvo por algunos detalles:
- línea 6: el nombre de visualización de la aplicación web ha cambiado a [mvc-personne-03]
El parámetro [urlControleur] ha desaparecido. En la versión anterior, se utilizaba para establecer el destino del POST de la vista [formulaire]. En esta nueva versión, el destino será la cadena vacía, c.a.d. La URL que muestra el navegador. Ya explicamos que esta siempre sería [http://localhost:8080/personne3/main], la que necesitamos para el POST de la vista [formulaire].
La página de inicio [index.jsp] cambia:
<%@ 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");
%>
- línea 5: la página [index.jsp] redirige al cliente a la URL del controlador [ServletPersonne] de la aplicación [/personne3].
7.4. El código de las vistas
7.4.1. La vista [formulaire]
Esta vista quedó así:

Se genera a partir de la página JSP [formulaire.jsp] siguiente:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%// se recuperan los datos del modelo
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
<html>
<head>
<title>Personne - formulaire</title>
<script language="javascript">
// -------------------------------
function effacer(){
// se borran los campos de entrada
with(document.frmPersonne){
txtNom.value="";
txtAge.value="";
}//con
}//borrar
// -------------------------------
function envoyer(){
// verificación de los parámetros antes de enviarlos
with(document.frmPersonne){
// el nombre no debe estar en blanco
champs=/^\s*$/.exec(txtNom.value);
if(champs!=null){
// el nombre está vacío
alert("Vous devez indiquer un nom");
txtNom.value="";
txtNom.focus();
// regreso a la interfaz visual
return;
}//si
// la edad debe ser un número entero positivo
champs=/^\s*\d+\s*$/.exec(txtAge.value);
if(champs==null){
// la edad es incorrecta
alert("Age incorrect");
txtAge.focus();
// regreso a la interfaz visual
return;
}//si
// los parámetros son correctos; se envían al servidor
submit();
}//con
}//enviar
</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>
Novedades:
- línea 56: el formulario tiene el nombre [frmPersonne]. Este nombre se utilizará en el código JavaScript. Cabe destacar la ausencia del atributo [action], lo que hace que el formulario [frmPersonne] se envíe a la URL que muestra el navegador.
- línea 70: el botón [Submit] cumple la función del botón [Envoyer] de las versiones anteriores
- línea 71: al hacer clic en el botón [Envoyer], del tipo [Button], se ejecuta la función de JavaScript [envoyer] definida en la línea 24
- línea 72: el botón [Rétablir] no ha cambiado de función
- línea 73: al hacer clic en el botón [Effacer], del tipo [Button], se ejecuta la función de JavaScript [effacer] definida en la línea 16
Antes de comentar el código de JavaScript, recordemos algunas notaciones:
JavaScript maneja la página que se muestra y su contenido como un árbol de objetos cuya raíz es el objeto [document]. En este documento, puede haber uno o varios formularios. [document.frmPersonne] se refiere al formulario con el nombre [frmPersonne] definido en la línea 56. Este formulario también contiene objetos. Los campos de entrada forman parte de ellos. Así, [document.frmPersonne.txtNom] hace referencia al objeto de imagen del campo de entrada HTML, definido en la línea 60. El objeto [txtNom] tiene diversas propiedades, entre ellas la propiedad [value], que designa el contenido del campo de entrada. Así, [document.frmPersonne.txtNom.value] designa el contenido del campo de entrada [txtNom].
- líneas 16-22: la función de JavaScript [effacer] coloca una cadena vacía en los campos de entrada [txtNom, txtAge].
- líneas 24-49: la función de JavaScript [envoyer] verifica la validez de los valores de los campos de entrada [txtNom, txtAge] antes de enviarlos. Para ello, utiliza expresiones regulares.
- línea 28: verifica si el valor del campo de entrada [txtNom] coincide con el patrón /s*, que significa 0 o más espacios. Si la respuesta es sí, significa que el usuario no ha ingresado ningún nombre. Si hay coincidencia con el patrón, la variable champs tendrá un valor diferente al del puntero null; de lo contrario, tendrá el valor null.
- línea 29: si hay coincidencia con el modelo
- línea 30: se muestra un mensaje al usuario
- línea 32: se coloca la cadena vacía en el campo [txtNom] (podría haber una secuencia de espacios)
- línea 33: se coloca el cursor parpadeante en el campo [txtNom]
- línea 34: se interrumpe la función. De esta manera, no se envían los valores ingresados al servidor en el campo POST.
- líneas 38-45: se sigue un procedimiento similar con el campo [txtAge]
- línea 47: si llegamos hasta aquí, significa que los valores ingresados son correctos. Entonces se envía (submit) el formulario [frmPersonne] al servidor web. Todo sucede entonces como si hubiéramos presionado el botón con la leyenda [Submit].
7.4.2. La vista [reponse]
Esta vista muestra los valores ingresados en el formulario cuando estos son válidos:
![]() | ![]() |
A diferencia de la versión anterior, la novedad solo aparece cuando se utiliza el enlace [Retour au formulaire] de la vista [réponse]:
![]() | ![]() |
La diferencia está en la URL que se muestra en [1]. En la versión anterior, esta era:
Aquí, la acción ya no forma parte de la URL porque se enviará mediante un POST en lugar de un GET. La nueva página JSP [reponse.jsp] es lqqqaaaaaaaaaqqAAAaaa
siguiente:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
// se recuperan los datos del modelo
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>
Novedades:
- líneas 35-37: el enlace [Retour au formulaire] contiene JavaScript. Al hacer clic en este enlace, se ejecuta el código JavaScript del atributo [href]. Como vimos en el análisis de [formulaire.jsp], sabemos que este código envía los valores de los campos de tipo <input>, <select>, ... del formulario [frmPersonne].
- Líneas 32-34: definen el formulario [frmPersonne]. Este solo tiene un campo de tipo <input type="hidden" ...>, es decir, un campo oculto. Este campo [action] sirve para transmitir al controlador el nombre de la acción que se debe ejecutar, en este caso [retourFormulaire].
7.4.3. La vista [erreurs]
Esta vista señala los errores de entrada en el formulario. La modificación realizada es la misma que para la vista [réponse]:
![]() | ![]() |
La diferencia radica en la URL que se muestra en [1]. En la versión anterior, esta era:
Aquí, la acción ya no forma parte de la URL porque se enviará mediante un POST en lugar de un GET. La nueva página JSP [reponse.jsp] es la siguiente:
<%@ 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" %>
<%
// se recuperan los datos del modelo
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");
}//para
%>
</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>
Novedades:
- líneas 30-32: la nueva gestión del clic en el enlace. Las explicaciones dadas al respecto en el estudio de [réponse.jsp] también son válidas aquí.
7.5. Pruebas de las vistas
Para realizar las pruebas de las vistas anteriores, duplicamos sus páginas JSP en la carpeta /WebContent/JSP del proyecto Eclipse:

Luego, en la carpeta JSP, se modifican las páginas de la siguiente manera:
[formulaire.jsp]:
...
<%
// -- prueba: se crea la plantilla de la página
session.setAttribute("nom","tintin");
session.setAttribute("age","30");
%>
<%// se recuperan los datos de la plantilla
String nom = (String) session.getAttribute("nom");
String age = (String) session.getAttribute("age");
%>
Se agregaron las líneas 4 y 5 para crear la plantilla que necesita la página de las líneas 9 y 10.
[reponse.jsp]:
...
<%
// -- prueba: se crea la plantilla de la página
request.setAttribute("nom","milou");
request.setAttribute("age","10");
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// se recuperan los datos de la plantilla
String nom=(String)request.getAttribute("nom");
String age=(String)request.getAttribute("age");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
...
Se agregaron las líneas 4 a 6 para crear la plantilla que necesita la página de las líneas 11 a 13.
[erreurs.jsp]:
<%
// -- prueba: se crea la plantilla de la página
ArrayList<String> erreurs1=new ArrayList<String>();
erreurs1.add("erreur1");
erreurs1.add("erreur2");
request.setAttribute("erreurs",erreurs1);
request.setAttribute("lienRetourFormulaire","Retour au formulaire");
%>
<%
// se recuperan los datos del modelo
ArrayList erreurs=(ArrayList)request.getAttribute("erreurs");
String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
Se agregaron las líneas 4 a 8 para crear la plantilla que necesita la página de las líneas 13 a 14.
Inicia Tomcat, si aún no lo has hecho, y luego solicita las siguientes URL:
![]() | ![]() |
![]() |
Sí, obtenemos las vistas esperadas.
7.6. El controlador [ServletPersonne]
El controlador [ServletPersonne] de la aplicación web [/personne3] procesará las siguientes acciones:
n.º | solicitud | origen | procesamiento |
1 | [GET /personne3/main] | URL ingresada por el usuario | - enviar la vista [formulaire] vacía |
2 | [POST /personne3/main] con parámetros [txtNom, txtAge, action=validationFormulaire] publicados | al hacer clic en el botón [Envoyer] de la vista [formulaire] | - verificar los valores de los parámetros [txtNom, txtAge] - si son incorrectos, enviar la vista [erreurs(erreurs)] - si son correctos, enviar la vista [reponse(nom,age)] |
3 | [POST /personne3/main] con parámetros [action=retourFormulaire] ostés | al hacer clic en el enlace [Regresar al formulario] de las vistas [réponse] y [erreurs]. | - Enviar la vista [formulaire] prellenada con los últimos valores ingresados |
Por lo tanto, tenemos una nueva acción que procesar: [POST /personne3/main] con el parámetro enviado [action=retourFormulaire], en lugar de la acción anterior [GET /personne3/main?action=retourFormulaire].
7.6.1. Estructura básica del controlador
El esqueleto del controlador [ServletPersonne] es idéntico al de la versión anterior.
Novedades:
- En la línea 11, la tabla [paramètres] ya no contiene el parámetro [urlControleur], el cual se ha eliminado del archivo [web.xml].
Los métodos [init, doValidationFormulaire] siguen siendo los mismos. Los métodos [doGet, doInit, doRetourFormulaire] cambian ligeramente.
7.6.2. El método [doGet]
El método [doGet] debe procesar la acción [POST /personne3/main] con el parámetro enviado [action=retourFormulaire]:
- líneas 6-9: procesamiento de la acción [POST /personne3/main] con el parámetro enviado [action=retourFormulaire]
7.6.3. El método [doInit]
Este método procesa la solicitud n.º 1 [GET /personne3/main]. Su código es el siguiente:
La novedad es que la vista [formulaire] que se muestra en la línea 8 ya no incluye el elemento [action] en su modelo.
7.6.4. El método [doRetourFormulaire]
Este método procesa la solicitud n.º 1 [POST /personne3/main] con [action=retourFormulaire] en los elementos enviados. Su código es el siguiente:
La novedad es que la vista [formulaire] que se muestra en la línea 14 ya no incluye el elemento [action] en su modelo.
7.7. Tests
Inicie o reinicie Tomcat después de haber integrado en él el proyecto de Eclipse [personne-mvc-03]. Solicite la URL [http://localhost:8080/personne3] y luego reanude las pruebas mostradas como ejemplo en el párrafo 7.1.















