Accueil > Non classé > Comment implémenter le pattern Post/Redirect/Get avec des Servlets

Comment implémenter le pattern Post/Redirect/Get avec des Servlets

Il existe 2 méthodes HTTP pour afficher une page web : Get et Post.

  • La méthode Get est utilisée lorsqu’on clique sur un lien ou pour afficher les résultats d’un formulaire de recherche. Dans ce 2ème cas, le fait que les paramètres de la requête soit présents dans l’url permet de bookmarker la page de résultats, ce qui n’est pas possible lorsqu’un formulaire utilise la méthode Post.
  • La méthode Post est généralement utilisée pour des formulaires contenant des données tapées par l’utilisateur et destinées à être traitées. C’est le cas des formulaires d’inscription, de login ou d’ajout d’un article à un panier.

Le problème avec la méthode Post, c’est le risque de double submit. En effet, après avoir soumis un formulaire, si un utilisateur tente de rafraîchir la page ou d’utiliser le bouton back du navigateur pour revenir à la page précédente, il obtient le message d’avertissement suivant :

Ce message peut faire peur aux utilisateurs, surtout après avoir soumis un formulaire de paiement.

Heureusement, grâce au design pattern Post/Redirect/Get (PRG), on peut éviter l’affichage de cette pop-up. Le principe du PRG est le suivant :

  • L’utilisateur soumet un formulaire avec la méthod Post
  • Le server traite les données et retourne au browser une réponse avec le code HTTP 303 (un redirect de type See Other) indicant l’url de la page de résultat
  • Le browser effectue une requête HTTP avec la méthode Get pour aller chercher la page de résultat

Il existe toutefois 2 inconvénients au design pattern PRG :

  • 2 allers-retours entre le client et le serveur au lieu d’un peut avoir un impact légèrement néfaste sur le temps de réponse de la page.
  • L’url de la page de résultat peut contenir des paramètres sensibles (qui ne seraient pas apparus dans l’url s’il n’y avait eu qu’un Post), ce qui peut poser problème au niveau de la sécurité.

Voici le code permettant d’implémenter le design pattern Post/Redirect/Get avec des servlets :

Environnement de développement :
jdk1.7
Eclipse Indigo
Tomcat 7.0.12

Tout d’abord, la JSP index.jsp contenant un formulaire avec un bouton submit :

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<%
	Boolean confirm = (Boolean)request.getAttribute("confirm");
%>

<!DOCTYPE html>
<html>
<body>
	<%
		if(confirm != null && confirm)
		{
			%>
			L'article a bien été ajouté au panier.
			<%
		}
		else
		{
			%>
			Cliquer pour ajouter l'article au panier.
			<%
		}
	%>

	<form action="/myapp/prgServlet" method="post" >
		<input type="submit" />
	</form>
</body>
</html>

Ensuite, la servlet vers laquelle le formulaire est posté, qui effectue la redirection 303 vers une autre servlet. On remarquera l’utilisation de l’annotation @WebServlet, ce qui évite d’avoir à déclarer la servlet dans le fichier web.xml :

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/prgServlet")
public class PRGServlet extends HttpServlet {

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) {

		response.setStatus(HttpServletResponse.SC_SEE_OTHER);
		response.setHeader("Location", "/myapp/confirmationServlet?confirm=true");
	}

}

Enfin, la servlet qui redirige vers la jsp correspondant à la page de résultat :

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/confirmationServlet")
public class ConfirmationServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		request.setAttribute("confirm",
				Boolean.valueOf(request.getParameter("confirm")));

		getServletContext().getRequestDispatcher("/index.jsp").forward(request,
				response);
	}
}

Dans un prochain article, nous verrons comment implémenter le design pattern Post/Redirect/Get avec Struts2.

  1. Pas encore de commentaire
  1. Pas encore de trackbacks