Skip to content

12. Aplicación web MVC [personne] – versión 7

12.1. Introducción

En esta versión, partimos de la base de que puede haber navegadores de los usuarios que hayan desactivado:

  1. el reenvío de las cookies que envía el servidor
  2. la ejecución del código JavaScript incrustado en las páginas HTML mostradas

No obstante, queremos que este tipo de navegadores puedan utilizar nuestra aplicación. El punto 2 nos remite a la versión 2 de nuestra aplicación, ya que el JavaScript se empezó a utilizar a partir de la versión 3. La versión 2 hacía funcionar la aplicación sin JavaScript, por lo que el punto 2 queda resuelto.

El punto 1 puede resultar complicado o no de gestionar. La versión 6 de nuestra aplicación funcionaba sin cookies. Al fusionar las versiones 2 y 6, obtenemos el resultado deseado. Vamos a añadir una restricción adicional: la aplicación debe gestionar una sesión. No es una restricción sin sentido. En una aplicación en la que los usuarios deben autenticarse, el servidor debe memorizar el par (identificador/contraseña) del usuario para evitar que tenga que autenticarse en cada página que solicite.

Hasta ahora hemos utilizado tres soluciones para almacenar información a lo largo de las interacciones entre el cliente y el servidor:

  1. la sesión
  2. las cookies
  3. los campos ocultos.

La solución 2 puede descartarse, ya que el navegador del cliente puede haber desactivado el uso de cookies.

La solución 3 es la de la versión 6 que hemos estudiado anteriormente. No se puede utilizar por motivos de seguridad. Si el par (nombre de usuario/contraseña) se incluye en cada página enviada al navegador, esto significa que transita por la red en cada intercambio entre el cliente y el servidor. Esto no es bueno para la seguridad de la aplicación. Por lo tanto, se puede considerar el uso del protocolo HTTPS, que cifra los intercambios entre el cliente y el servidor. Sin embargo, utilizarlo para cada página de la aplicación aumentará la carga del servidor.

Podríamos querer descartar la solución 1 porque también se basa en cookies. Durante el primer intercambio entre el cliente y el servidor, el servidor envía al cliente un token de sesión que este devolverá al servidor en cada nueva solicitud. Gracias a este token, el servidor podrá reconocer a su cliente y asignarle la información que había almacenado durante un intercambio anterior. El servidor envía el token de sesión en una cookie. El navegador que no haya desactivado las cookies puede reenviarle esta cookie en sus siguientes solicitudes. Si las ha desactivado, dispone de otra solución: puede incluir el token de sesión en la URL que solicita. Esto es lo que vemos ahora al retomar el análisis del archivo [index.jsp] de la versión 4:


<%@ 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="/main"/>

Recordemos que la línea 5 anterior redirige al cliente a la URL [/personne4/main?jsessionid=XX], donde XX es el token de sesión, tal y como muestra la captura de pantalla siguiente, obtenida tras solicitar la URL [http://localhost:8080/personne4]:

Image

Analicemos más detenidamente el funcionamiento de la etiqueta <c:redirect> en lo que respecta al token de sesión. Tomemos como ejemplo un navegador en el que se aceptan las cookies. A continuación, configuramos el navegador Firefox:

Image

En [1], habilitamos las cookies y en [2] eliminamos las que ya existen para partir de una situación conocida. A continuación, solicitamos la URL [http://localhost:8080/personne4]. Obtenemos la siguiente respuesta:

Image

La solicitud inicial del cliente, HTTP, fue la siguiente:

1
2
3
4
5
6
7
8
9
GET /personne4/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0,5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

Cabe señalar simplemente que el cliente no envía ninguna cookie de sesión. La respuesta HTTP enviada por el servidor es la siguiente:

1
2
3
4
5
6
7
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC; Path=/personne4
Location: http://localhost:8080/persona4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:10:05 GMT
  • línea 1: el servidor solicita al cliente que se redirija
  • línea 3: el servidor envía un token de sesión asociado al atributo [JSESSIONID]
  • línea 4: la URL de redirección contiene el token de sesión. La etiqueta <c:redirect> lo ha colocado allí porque el cliente no había enviado ninguna cookie de sesión.

El navegador, al que se le pidió que se redirigiera, realizó a continuación la siguiente solicitud:

GET /personne4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0,5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC
  • línea 1: solicita la URL de redirección, con el token de sesión incluido. Por eso, en la captura de pantalla, el navegador muestra esta URL.
  • línea 10: el navegador devuelve el token de sesión que le envió el servidor en el intercambio anterior. Este es el funcionamiento normal de las cookies cuando están permitidas en el navegador del cliente. Si no es así, las cookies recibidas no se devuelven.

El servidor respondió lo siguiente a esta segunda solicitud:

1
2
3
4
5
HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2376
Date: Tue, 23 May 2006 09:10:05 GMT

Ha encontrado la página que se le solicitaba y la envía. Cabe destacar que ya no envía el token de sesión. Este es el funcionamiento normal del token de sesión: el servidor lo envía al navegador una única vez en forma de cookie y, a continuación, el navegador lo reenvía en cada solicitud para que se le reconozca.

Ahora, con el mismo navegador, volvamos a solicitar la URL [http://localhost:8080/personne4] escribiéndola manualmente. Obtendremos entonces la siguiente página:

Image

Observamos que la URL que muestra el navegador ya no contiene el token de sesión. Veamos el primer intercambio entre el cliente y el servidor:

El navegador ha realizado la siguiente solicitud:

GET /personne4 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0,5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

Es exactamente la misma solicitud que la anterior, con una diferencia: en la línea 10, el navegador devuelve el token de sesión que había recibido en el primer intercambio. Una vez más, este es el funcionamiento normal si las cookies del navegador están activas.

El servidor envió la siguiente respuesta:

1
2
3
4
5
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Location: http://localhost:8080/persona4/
Transfer-Encoding: chunked
Date: Tue, 23 May 2006 09:24:39 GMT

Solicita al cliente que se redirija. Como ha recibido un token de sesión del cliente, continúa con dicha sesión y no envía un nuevo token de sesión. Por la misma razón, la etiqueta <c:redirect> no incluye este token de sesión en la URL de redirección. Por eso, la URL que se muestra en la captura de pantalla anterior no contiene ningún token de sesión.

De todo esto se desprende la siguiente regla: la etiqueta <c:redirect> solo incluye el token de sesión en la URL de redirección si el cliente no ha enviado el encabezado HTTP:

Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

Esta regla también se aplica a la etiqueta <c:url>, con la que nos encontraremos más adelante.

¿Qué ocurre con un navegador en el que se han desactivado las cookies? Probémoslo. En primer lugar, reiniciamos el navegador:

Image

En [1], desactivamos las cookies y en [2] eliminamos las que ya existen para partir de una situación conocida. A continuación, solicitamos la URL [http://localhost:8080/personne4]. Obtenemos la siguiente respuesta:

Image

Obtenemos el mismo resultado que antes. Sin embargo, los intercambios HTTP no son exactamente los mismos:

GET /personne4/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0,5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=911B8156E0A9D32C2D256020C898E05C; Path=/personne4
Location: http://localhost:8080/persona4/main;jsessionid=911B8156E0A9D32C2D256020C898E05C
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:39:55 GMT

GET /personne4/main;jsessionid=911B8156E0A9D32C2D256020C898E05C HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2376
Date: Tue, 23 May 2006 09:39:55 GMT
  • líneas 1-9: la solicitud n.º 1 del navegador. No envía ninguna cookie de sesión.
  • líneas 11-17: la respuesta del servidor que le pide que se redirija a otra URL. Envía una cookie de sesión en la línea 13: la etiqueta <c:redirect> ha incluido el token en la URL de redirección de la línea 14.
  • líneas 19-27: la solicitud n.º 2 del navegador. No devuelve la cookie de sesión que el servidor le acaba de enviar porque tiene desactivadas las cookies.
  • líneas 29-33: la respuesta del servidor. Se puede observar que, aunque el navegador no le haya enviado ninguna cookie de sesión, el servidor no inicia una nueva sesión, como cabría esperar. Esto se aprecia en el hecho de que no envía el encabezado HTTP [Set-Cookie] como lo había hecho en la línea 13. Esto significa que continúa con la sesión anterior. Ha podido recuperarla gracias al token de sesión presente en la URL solicitada por el navegador en la línea 19.

Cabe destacar que el servidor realiza el seguimiento de una sesión recuperando el token de sesión enviado por el cliente, de dos formas posibles:

  • en el encabezado HTTP [Set-Cookie] enviado por el cliente
  • en la URL solicitada por el cliente

Ahora, con el mismo navegador, volvamos a solicitar la URL [http://localhost:8080/personne4] escribiéndola manualmente, tal y como se hacía cuando las cookies estaban permitidas. Entonces obtendremos la siguiente página:

Image

El resultado es diferente al obtenido cuando las cookies estaban permitidas: el token de sesión aparece en la URL que muestra el navegador. Analicemos este resultado sin entrar en detalle en los intercambios HTTP que han tenido lugar:

[cookies autorisés]

  • En la segunda solicitud de la URL [http://localhost:8080/personne4], el navegador del cliente había devuelto la cookie de sesión que había recibido del servidor durante la primera solicitud de esa misma URL. Por lo tanto, la etiqueta <c:redirect> no había incluido el token de sesión en la dirección de redirección.

[cookies inhibés]

  • En la segunda solicitud de la URL [http://localhost:8080/personne4], el navegador del cliente no envía la cookie de sesión que recibió del servidor durante la primera solicitud de esa misma URL, ya que sus cookies están desactivadas. Por lo tanto, la etiqueta <c:redirect> incluye el token de sesión en la dirección de redirección. Por eso aparece en la captura de pantalla anterior.

Las etiquetas <c:redirect> y <c:url> permiten incluir el token de sesión en las URL. Esta es la solución que se propone aquí.

12.2. El proyecto Eclipse

Para crear el proyecto Eclipse [mvc-personne-07] de la aplicación web [/personne7], se duplicará el proyecto [mvc-personne-06] siguiendo el procedimiento descrito en el apartado 6.2.

12.3. Configuración de la aplicación web [personne7]

El archivo web.xml de la aplicación /personne7 es el siguiente:


<?xml version="1.0" encoding="UTF-8"?>
...
    <display-name>mvc-personne-07</display-name>
...

Este archivo es idéntico al de la versión anterior, salvo en la línea 3, donde el nombre de visualización de la aplicación web ha cambiado a [mvc-personne-07]. La página de inicio [index.jsp] no cambia.


...
<c:redirect url="/do/formulaire"/>

12.4. El código de las vistas

Las vistas [formulaire, réponse, erreurs] vuelven a ser lo que eran en la versión 2, c.a.d, sin JavaScript. Sin embargo, conservan las etiquetas JSTL de las últimas versiones.

12.4.1. La vista [formulaire]

Image

Se han eliminado los botones asociados al código JavaScript.

[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">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
  <head>
    <title>Personne - formulaire</title>
  </head>
  <body>
    <center>
      <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" action="<c:url value="validationFormulaire"/>" 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" name="bouton" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="submit" name="bouton" value="Effacer"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>
  • línea 14: la URL de destino de POST se escribe con la etiqueta <c:url> para que el token de sesión se incluya en ella en caso de que el cliente sea un navegador que no envíe el encabezado HTTP [Cookie].
  • El formulario tiene dos botones de tipo [submit]: [Envoyer] (línea 28) y [Effacer] (línea 30). Ambos botones tienen el mismo nombre: bouton. Al pulsar el botón POST, el navegador enviará el parámetro:
  • botón=Enviar si la solicitud POST ha sido provocada por el botón [Enviar]
  • botón=Borrar si la solicitud POST ha sido provocada por el botón [Borrar]

Este parámetro nos ayudará a definir la acción exacta que hay que realizar, ya que la URL [/do/validationFormulaire] corresponde ahora a dos acciones distintas.

12.4.2. La vista [réponse]

Image

[réponse.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">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td>${nom}</td>
      </tr>
        <tr>
          <td>Age</td>
        <td>${age}</td>
      </tr>
    </table>      
    <br>
    <a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
  </body>
</html>

  • línea 24: la URL de destino de HREF se escribe con la etiqueta <c:url> para que el token de sesión se incluya en ella en caso de que el cliente sea un navegador que no envíe el encabezado HTTP [Cookie].

12.4.3. La vista [erreurs]

Image

[erreurs.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">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
  </body>
</html>

  • línea 18: la URL de destino de HREF se escribe con la etiqueta <c:url> para que el token de sesión se incluya en ella en caso de que el cliente sea un navegador que no envíe el encabezado HTTP [Cookie].

Se invita al lector a probar estas nuevas vistas siguiendo el principio visto en las versiones anteriores.

12.5. El controlador [ServletPersonne]

El controlador [ServletPersonne] de la aplicación web [/personne7] es el siguiente:

package istia.st.servlets.personne;

...

@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
    // parámetros de instancia
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse","lienRetourFormulaire"};
    private Map params=new HashMap<String,String>();

    // inicialización
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
    }

    // GET
    @SuppressWarnings("unchecked")
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

...
        // se recupera el método de envío de la solicitud
        String méthode=request.getMethod().toLowerCase();
        // se recupera la acción que se debe ejecutar
        String action=request.getPathInfo();
...
        if(méthode.equals("post") && action.equals("/validationFormulaire")){
            // validación del formulario de introducción de datos
            doValidationFormulaire(request,response);
            return;
        }
        if(méthode.equals("get") && action.equals("/retourFormulaire")){
            // vuelta al formulario de introducción de datos
            doRetourFormulaire(request,response);
            return;
        }
        // otros casos
        doInit(request,response);
    }

    // visualización del formulario vacío
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
...
    }

    // visualización del formulario prellenado
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // Se muestra el formulario
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

    // Visualización del formulario vacío
    void doEffacer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // se prepara la plantilla del formulario
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", "");
        session.setAttribute("age", "");
        // se muestra el formulario
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

    // validación del formulario
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
        // se recupera el botón que ha provocado el POST
        String bouton = request.getParameter("bouton").toLowerCase();
        // procesamiento según el botón que ha provocado el POST
        if(bouton==null){
            doInit(request,response);
            return;
        }
        if("envoyer".equals(bouton)){
            doEnvoyer(request,response);
            return;
        }
        if("effacer".equals(bouton)){
            doEffacer(request,response);
            return;
        }
    }

    // validación del formulario
    void doEnvoyer(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
        // se recuperan los parámetros
        String nom = request.getParameter("txtNom");
        String age = request.getParameter("txtAge");
        // que se almacenan en la sesión
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", nom);
        session.setAttribute("age", age);
        // el enlace de vuelta al formulario se incluye en la plantilla de vistas [réponse, erreurs]
        request.setAttribute("lienRetourFormulaire", (String)params.get("lienRetourFormulaire"));    
        // ¿Se comprueban los parámetros
        ArrayList<String> erreursAppel = new ArrayList<String>();
    ...
        // ¿Hay errores en los parámetros?
        if (erreursAppel.size() != 0) {
            // se envía la página de errores
            request.setAttribute("erreurs", erreursAppel);
            getServletContext().getRequestDispatcher(urlErreurs).forward(
                    request, response);
            return;
        }
        // los parámetros son correctos: se envía la página de respuesta
        getServletContext().getRequestDispatcher((String)params.get("urlReponse")).forward(request,
                response);
        return;
    }

    // enviar
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
...
    }
}
  • línea 35: la acción [/retourFormulaire] se realiza mediante un GET y ya no mediante un POST como en la versión anterior.
  • líneas 70-87: la acción [/validationFormulaire] se realiza mediante una acción POST, que se activa al hacer clic enuno de los botones [Envoyer] o [Effacer] de la vista [formulaire]. El método [doValidationFormulaire] gestiona estos dos casos mediante dos métodos diferentes.
  • líneas 90-103: el método [doEnvoyer] corresponde al método [doValidationFormulaire] de la versión anterior. Los datos introducidos se almacenan en la sesión (líneas 96-98), mientras que en la versión anterior se colocaban en la consulta.
  • líneas 58-67: el nuevo método [doEffacer] debe mostrar un formulario vacío. Se podría recurrir al método [doInit], que ya realiza esta tarea. Aprovechamos para borrar también los elementos [nom, age] de la sesión, de modo que esta siga reflejando el último estado del formulario.
  • Líneas 50-55: solicitan la visualización de la vista [formulaire] sin una inicialización aparente de la plantilla de dicha vista. Esta plantilla está compuesta, de hecho, por los elementos [nom, age] que ya se encuentran en la sesión. No es necesario hacer nada más.

12.6. Pruebas

Inicie o reinicie Tomcat tras haber integrado en él el proyecto Eclipse [personne-mvc-07] y, a continuación, solicite la URL [http://localhost:8080/personne7] con un navegador en el que se hayan desactivado las cookies y se hayan eliminado las ya existentes. Se obtiene la siguiente respuesta:

Image

El código fuente recibido por el navegador es el siguiente:

1
2
3
<form name="frmPersonne" action="validationFormulaire;jsessionid=9D4CC83FEFB51AE78B1FD71EC66F9EF3" method="post">
...
</form>

En la línea 1, el token de sesión se encuentra en la URL de destino de POST.

Rellenemos el formulario y enviémoslo:

Image

El código fuente que recibe el navegador es el siguiente:

1
2
3
4
...
    <br>
    <a href="retourFormulaire;jsessionid=9D4CC83FEFB51AE78B1FD71EC66F9EF3">Retour au formulaire</a>
  </body>

En la línea 3, el token de sesión aparece en la URL de destino del enlace.