Skip to content

12. Aplicação web MVC [personne] – versão 7

12.1. Introduction

Nesta versão, partimos do princípio de que podem existir navegadores dos utilizadores que tenham desativado:

  1. o reenvio dos cookies enviados pelo servidor
  2. a execução de código JavaScript incorporado nas páginas HTML apresentadas

No entanto, queremos que este tipo de navegadores possa utilizar a nossa aplicação. O ponto 2 remete-nos para a versão 2 da nossa aplicação, uma vez que o JavaScript passou a ser utilizado a partir da versão 3. A versão 2 permitia que a aplicação funcionasse sem JavaScript, pelo que o ponto 2 está resolvido.

O ponto 1 pode ou não ser complicado de gerir. A versão 6 da nossa aplicação funcionava sem cookies. Ao fundir as versões 2 e 6, obtemos o resultado pretendido. Vamos adicionar uma restrição adicional: a aplicação deve gerir uma sessão. Esta restrição não é sem sentido. Numa aplicação em que os utilizadores têm de se autenticar, o servidor deve memorizar o par (identificador/palavra-passe) do utilizador para evitar que este tenha de se autenticar em cada página que solicitar.

Até agora, utilizámos três soluções para memorizar informações ao longo das trocas cliente/servidor:

  1. a sessão
  2. os cookies
  3. os campos ocultos.

A solução 2 pode ser descartada, uma vez que o navegador do cliente pode ter desativado a utilização de cookies.

A solução 3 é a da versão 6 anteriormente analisada. Não pode ser utilizada por razões de segurança. Se o par (nome de utilizador/palavra-passe) estiver encapsulado em cada página enviada ao navegador, isso significa que transita pela rede em cada troca cliente/servidor. Isto não é bom para a segurança da aplicação. Pode-se então considerar a utilização do protocolo HTTPS, que encripta as trocas cliente/servidor. No entanto, utilizá-lo em todas as páginas da aplicação irá sobrecarregar o servidor.

Poder-se-ia querer eliminar a solução 1 porque também se baseia em cookies. Durante a primeira troca cliente/servidor, o servidor envia ao cliente um token de sessão que este irá reenviar ao servidor em cada nova solicitação. Graças a este token, o servidor poderá reconhecer o seu cliente e atribuir-lhe informações que tinha memorizado durante uma troca anterior. O token de sessão é enviado pelo servidor num cookie. O navegador que não tenha desativado os cookies pode reenviar esse cookie nas suas solicitações seguintes. Se tiver desativado os cookies, dispõe de outra solução: pode incluir o token de sessão no URL que solicita. É isso que vemos agora, retomando a análise do ficheiro [index.jsp] da versão 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"/>

Recorde-se que a linha 5 acima redireciona o cliente para a URL [/personne4/main?jsessionid=XX], em que XX é o token de sessão, tal como mostra a captura de ecrã abaixo, obtida após ter solicitado a URL [http://localhost:8080/personne4]:

Image

Vamos analisar mais detalhadamente o funcionamento da tag <c:redirect> no que diz respeito ao token de sessão. Consideremos um navegador em que os cookies são aceites. Abaixo, configuramos o navegador Firefox:

Image

Em [1], autorizamos os cookies e, em [2], eliminamos os que já existem para partirmos de uma situação conhecida. Em seguida, solicitamos o URL [http://localhost:8080/personne4]. Obtemos a seguinte resposta:

Image

O pedido inicial do cliente, HTTP, foi o seguinte:

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

Note-se simplesmente que o cliente não envia nenhum cookie de sessão. A resposta HTTP enviada pelo servidor é a seguinte:

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/pessoa4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:10:05 GMT
  • linha 1: o servidor solicita ao cliente que se redirecione
  • linha 3: o servidor envia um token de sessão associado ao atributo [JSESSIONID]
  • linha 4: o URL de redirecionamento contém o token de sessão. A tag <c:redirect> inseriu-o ali porque o cliente não tinha enviado nenhum cookie de sessão.

O navegador, ao qual foi solicitado que se redirecionasse, efetuou então o seguinte pedido:

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
  • linha 1: solicita o URL de redirecionamento, incluindo o token de sessão. É por isso que, na captura de ecrã, o navegador apresenta esse URL.
  • linha 10: o navegador reenvia o token de sessão que o servidor lhe enviou na troca anterior. Este é o funcionamento normal dos cookies quando estes estão autorizados no navegador do cliente. Se não for esse o caso, os cookies recebidos não são reenviados.

O servidor respondeu o seguinte a esta segunda solicitação:

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

Encontrou a página que lhe foi solicitada e envia-a. Note-se que já não envia o token de sessão. Este é o funcionamento normal do token de sessão: é enviado ao navegador uma única vez pelo servidor sob a forma de um cookie e o navegador reenvia-o posteriormente em cada pedido para ser reconhecido.

Agora, com o mesmo navegador, vamos solicitar novamente a URL [http://localhost:8080/personne4], digitando-a manualmente. Obtemos então a seguinte página:

Image

Verifica-se que a URL apresentada pelo navegador já não contém o token de sessão. Vejamos a primeira troca de dados entre o cliente e o servidor:

O navegador efetuou o seguinte pedido:

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

É exatamente a mesma solicitação da vez anterior, mas com uma diferença: na linha 10, o navegador reenvia o token de sessão que tinha recebido na primeira troca. Mais uma vez, este é o funcionamento normal se os cookies do navegador estiverem ativos.

O servidor enviou a seguinte resposta:

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

Solicita ao cliente que se redirecione. Como recebeu um token de sessão do cliente, dá continuidade à mesma e não envia um novo token de sessão. Pela mesma razão, a tag <c:redirect> não inclui este token de sessão no URL de redirecionamento. É por isso que o URL apresentado na captura de ecrã acima não contém nenhum token de sessão.

Daqui, fica a seguinte regra: a tag <c:redirect> só inclui o token de sessão na URL de redirecionamento se o cliente não tiver enviado o cabeçalho HTTP:

Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

Esta regra também se aplica à tag <c:url>, com a qual teremos oportunidade de nos deparar mais tarde.

O que acontece num navegador em que os cookies foram desativados? Vamos experimentar. Primeiro, reiniciamos o navegador:

Image

Em [1], desativamos os cookies e, em [2], eliminamos os que já existem, para partirmos de uma situação conhecida. Em seguida, solicitamos a URL [http://localhost:8080/personne4]. Obtemos a seguinte resposta:

Image

Obtemos o mesmo resultado que anteriormente. No entanto, as trocas HTTP não são exatamente as mesmas:

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/pessoa4/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
  • linhas 1-9: o pedido n.º 1 do navegador. Este não envia nenhum cookie de sessão.
  • linhas 11-17: a resposta do servidor que lhe pede para redirecionar-se para outro URL. Envia um cookie de sessão na linha 13: a tag <c:redirect> incluiu o token no URL de redirecionamento da linha 14.
  • linhas 19-27: o pedido n.º 2 do navegador. Este não devolve o cookie de sessão que o servidor acabou de lhe enviar, porque os seus cookies estão desativados.
  • linhas 29-33: a resposta do servidor. É possível constatar que, embora o navegador não lhe tenha enviado um cookie de sessão, o servidor não inicia, no entanto, uma nova sessão, como seria de esperar. Isto verifica-se pelo facto de não enviar o cabeçalho HTTP [Set-Cookie], tal como tinha feito na linha 13. Isto significa que dá continuidade à sessão anterior. Conseguiu recuperá-la graças ao token de sessão presente no URL solicitado pelo navegador na linha 19.

É importante notar que o servidor acompanha uma sessão, recuperando o token de sessão enviado pelo cliente, de duas formas possíveis:

  • no cabeçalho HTTP [Set-Cookie] enviado pelo cliente
  • na URL solicitada pelo cliente

Agora, com o mesmo navegador, vamos solicitar novamente a URL [http://localhost:8080/personne4], digitando-a manualmente, tal como foi feito quando os cookies estavam autorizados. Obtemos então a seguinte página:

Image

Temos um resultado diferente do obtido quando os cookies estavam autorizados: o token de sessão está na URL apresentada pelo navegador. Vamos explicar este resultado sem analisar as trocas de dados HTTP que ocorreram:

[cookies autorisés]

  • na segunda solicitação da URL [http://localhost:8080/personne4], o navegador do cliente tinha reenviado o cookie de sessão que tinha recebido do servidor na primeira solicitação dessa mesma URL. A tag <c:redirect> não tinha, portanto, incluído o token de sessão no endereço de redirecionamento.

[cookies inhibés]

  • Na segunda solicitação da URL [http://localhost:8080/personne4], o navegador do cliente não envia o cookie de sessão que recebeu do servidor na primeira solicitação dessa mesma URL, uma vez que os seus cookies estão desativados. A tag <c:redirect> inclui, portanto, o token de sessão no endereço de redirecionamento. É por isso que ele aparece na captura de ecrã acima.

As tags <c:redirect> e <c:url> permitem incluir o token de sessão nas URLs. É esta a solução aqui proposta.

12.2. O projeto Eclipse

Para criar o projeto Eclipse [mvc-personne-07] da aplicação web [/personne7], duplicaremos o projeto [mvc-personne-06], seguindo o procedimento descrito no parágrafo 6.2.

12.3. Configuração da aplicação web [personne7]

O ficheiro web.xml da aplicação /personne7 é o seguinte:


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

Este ficheiro é idêntico ao da versão anterior, exceto na linha 3, onde o nome de exibição da aplicação web mudou para [mvc-personne-07]. A página inicial [index.jsp] não sofre alterações.


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

12.4. O código das vistas

As vistas [formulaire, réponse, erreurs] voltam a ser o que eram na versão 2, c.a.d, sem JavaScript. No entanto, mantêm as balizas JSTL das últimas versões.

12.4.1. A vista [formulaire]

Image

Foram removidos os botões associados ao 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>
  • linha 14: o URL de destino do POST é escrito com a baliza <c:url> para que o token de sessão nele conste, caso o cliente seja um navegador que não envie o cabeçalho HTTP [Cookie].
  • O formulário tem dois botões do tipo [submit]: [Envoyer] (linha 28) e [Effacer] (linha 30). Ambos os botões têm o mesmo nome: bouton. Quando o POST for acionado, o navegador enviará o parâmetro:
  • botão=Enviar se o POST tiver sido desencadeado pelo botão [Enviar]
  • botão=Apagar se a solicitação POST tiver sido desencadeada pelo botão [Apagar]

É este parâmetro que nos ajudará a definir a ação exata a realizar, uma vez que a URL [/do/validationFormulaire] corresponde agora a duas ações distintas.

12.4.2. A 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>

  • linha 24: a URL de destino do HREF é escrita com a baliza <c:url> para que o token de sessão nela conste, caso o cliente seja um navegador que não envie o cabeçalho HTTP [Cookie].

12.4.3. A 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>

  • linha 18: o URL de destino do HREF é escrito com a baliza <c:url> para que o token de sessão nele conste, caso o cliente seja um navegador que não envie o cabeçalho HTTP [Cookie].

Convidamos o leitor a testar estas novas vistas seguindo o princípio apresentado nas versões anteriores.

12.5. O controlador [ServletPersonne]

O controlador [ServletPersonne] da aplicação web [/personne7] é o seguinte:

package istia.st.servlets.personne;

...

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

     // inicialização
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
    }

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

...
         // recupera-se o método de envio da solicitação
        String méthode=request.getMethod().toLowerCase();
         // recupera-se a ação a executar
        String action=request.getPathInfo();
...
        if(méthode.equals("post") && action.equals("/validationFormulaire")){
             // validação do formulário de introdução de dados
            doValidationFormulaire(request,response);
            return;
        }
        if(méthode.equals("get") && action.equals("/retourFormulaire")){
             // regresso ao formulário de introdução de dados
            doRetourFormulaire(request,response);
            return;
        }
         // outros casos
        doInit(request,response);
    }

     // exibição do formulário em branco
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
...
    }

     // exibição do formulário pré-preenchido
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         // exibe-se o formulário
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

     // exibição do formulário vazio
    void doEffacer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
         // prepara-se o modelo do formulário
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", "");
        session.setAttribute("age", "");
         // exibe-se o formulário
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

     // validação do formulário
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
         // recuperar o botão que provocou o POST
        String bouton = request.getParameter("bouton").toLowerCase();
         // processamento de acordo com o botão que provocou o POST
        if(bouton==null){
            doInit(request,response);
            return;
        }
        if("envoyer".equals(bouton)){
            doEnvoyer(request,response);
            return;
        }
        if("effacer".equals(bouton)){
            doEffacer(request,response);
            return;
        }
    }

     // validação do formulário
    void doEnvoyer(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
         // recuperam-se os parâmetros
        String nom = request.getParameter("txtNom");
        String age = request.getParameter("txtAge");
         // que são memorizados na sessão
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", nom);
        session.setAttribute("age", age);
         // o link de retorno ao formulário é inserido no modelo das vistas [réponse, erreurs]
        request.setAttribute("lienRetourFormulaire", (String)params.get("lienRetourFormulaire"));    
         // verificação dos parâmetros
        ArrayList<String> erreursAppel = new ArrayList<String>();
    ...
         // Existem erros nos parâmetros?
        if (erreursAppel.size() != 0) {
             // envia-se a página de erros
            request.setAttribute("erreurs", erreursAppel);
            getServletContext().getRequestDispatcher(urlErreurs).forward(
                    request, response);
            return;
        }
         // os parâmetros estão corretos — enviamos a página de resposta
        getServletContext().getRequestDispatcher((String)params.get("urlReponse")).forward(request,
                response);
        return;
    }

     // envio
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
...
    }
}
  • linha 35: a ação [/retourFormulaire] é executada por um GET e já não por um POST, como na versão anterior.
  • linhas 70-87: a ação [/validationFormulaire] é executada por um POST, acionado por um clique numum dos botões [Envoyer] ou [Effacer] da vista [formulaire]. O método [doValidationFormulaire] trata estes dois casos através de dois métodos diferentes.
  • linhas 90-103: o método [doEnvoyer] corresponde ao método [doValidationFormulaire] da versão anterior. Os dados introduzidos são colocados na sessão (linhas 96-98), enquanto na versão anterior eram colocados na consulta.
  • linhas 58-67: o novo método [doEffacer] deve apresentar um formulário vazio. Seria possível recorrer ao método [doInit], que já realiza essa tarefa. Aproveita-se esta oportunidade para eliminar também os elementos [nom, age] da sessão, para que esta continue a refletir o estado mais recente do formulário.
  • linhas 50-55: solicitam a exibição da vista [formulaire] sem inicialização aparente do modelo dessa vista. Este modelo é, na verdade, constituído pelos elementos [nom, age] já presentes na sessão. Não é necessário fazer mais nada.

12.6. Tests

Inicie ou reinicie o Tomcat após ter integrado o projeto Eclipse [personne-mvc-07] e, em seguida, aceda ao URL [http://localhost:8080/personne7] com um navegador no qual os cookies foram desativados e os já existentes foram eliminados. Obtém-se a seguinte resposta:

Image

O código-fonte recebido pelo navegador é o seguinte:

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

Na linha 1, o token de sessão encontra-se no URL de destino de POST.

Preenchamos o formulário e submetamo-lo:

Image

O código-fonte recebido pelo navegador é o seguinte:

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

Linha 3, o token de sessão está no URL de destino do link.