107 votes

DoGet et doPost dans les Servlets

J'ai développé une page HTML qui envoie des informations à une Servlet. Dans la Servlet, j'utilise les méthodes doGet() et doPost():

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException  {

     String id = req.getParameter("realname");
     String password = req.getParameter("mypassword");
}

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {

    String id = req.getParameter("realname");
    String password = req.getParameter("mypassword");
}

Dans le code de la page HTML qui appelle la Servlet :

    Nom d'utilisateur : 
    Mot de passe : 

Lorsque j'utilise method = "get" dans la Servlet, j'obtiens la valeur de l'identifiant et du mot de passe, cependant lorsque j'utilise method = "post", l'identifiant et le mot de passe sont définis sur null. Pourquoi ne récupère-je pas les valeurs dans ce cas?

Une autre chose que j'aimerais savoir est comment utiliser les données générées ou validées par la Servlet. Par exemple, si la Servlet montrée ci-dessus authentifie l'utilisateur, j'aimerais afficher l'identifiant de l'utilisateur dans ma page HTML. Je devrais pouvoir envoyer la chaîne 'id' en réponse et utiliser ces informations dans ma page HTML. Est-ce possible?

0 votes

Comment utilisez-vous la méthode post en HTML ?

0 votes

Et aussi, pourquoi avez-vous besoin d'une boucle aussi étrange sur les noms de paramètres?

1 votes

Avez-vous essayé de supprimer `enctype=multipart/form-data`? Je soupçonne que c'est votre problème.

202voto

BalusC Points 498232

Introduction

Vous devez utiliser doGet() lorsque vous voulez intercepter sur Demandes HTTP GET . Vous devez utiliser doPost() lorsque vous voulez intercepter sur Demandes HTTP POST . C'est tout. Ne portez pas l'un vers l'autre ou vice versa (comme dans le malheureux système de génération automatique de Netbeans). processRequest() méthode). Cela n'a aucun sens.

GET

Habituellement, les requêtes HTTP GET sont idempotent . C'est-à-dire que vous obtenez exactement le même résultat à chaque fois que vous exécutez la requête (sans tenir compte de l'autorisation/authentification et de la nature temporelle de la page - résultats de recherche, dernières nouvelles, etc.) Nous pouvons parler d'une demande de signet. Cliquer sur un lien, cliquer sur un signet, saisir une URL brute dans la barre d'adresse du navigateur, etc. déclenchera une requête HTTP GET. Si une servlet est à l'écoute de l'URL en question, alors sa fonction doGet() sera appelée. Il est généralement utilisé pour prétraiter une demande. C'est-à-dire qu'il s'agit d'effectuer des opérations commerciales avant de présenter la sortie HTML d'une JSP, comme la collecte de données pour les afficher dans un tableau.

@WebServlet("/products")
public class ProductsServlet extends HttpServlet {

    @EJB
    private ProductService productService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Product> products = productService.list();
        request.setAttribute("products", products); // Will be available as ${products} in JSP
        request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
    }

}

Notez que le fichier JSP est explicitement placé dans le répertoire /WEB-INF afin d'empêcher les utilisateurs finaux d'y accéder directement sans invoquer le servlet de prétraitement (et donc de se tromper en voyant une table vide).

<table>
    <c:forEach items="${products}" var="product">
        <tr>
            <td>${product.name}</td>
            <td><a href="product?id=${product.id}">detail</a></td>
        </tr>
    </c:forEach>
</table>

De même, les liens de visualisation/modification des détails, comme indiqué dans la dernière colonne ci-dessus, sont généralement idempotents.

@WebServlet("/product")
public class ProductServlet extends HttpServlet {

    @EJB
    private ProductService productService;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Product product = productService.find(request.getParameter("id"));
        request.setAttribute("product", product); // Will be available as ${product} in JSP
        request.getRequestDispatcher("/WEB-INF/product.jsp").forward(request, response);
    }

}

<dl>
    <dt>ID</dt>
    <dd>${product.id}</dd>
    <dt>Name</dt>
    <dd>${product.name}</dd>
    <dt>Description</dt>
    <dd>${product.description}</dd>
    <dt>Price</dt>
    <dd>${product.price}</dd>
    <dt>Image</dt>
    <dd><img src="productImage?id=${product.id}" /></dd>
</dl>

POST

Les demandes HTTP POST ne sont pas idempotentes. Si l'utilisateur final a préalablement soumis un formulaire POST sur une URL, qui n'a pas effectué de redirection, alors l'URL n'est pas nécessairement enregistrable. Les données du formulaire soumis ne sont pas reflétées dans l'URL. Copier l'URL dans une nouvelle fenêtre ou un nouvel onglet du navigateur ne donne pas nécessairement le même résultat qu'après l'envoi du formulaire. Une telle URL ne peut donc pas être marquée d'un signet. Si une servlet est à l'écoute de l'URL en question, alors sa fonction doPost() sera appelé. Il est généralement utilisé pour post-traitement une demande. C'est-à-dire collecter des données à partir d'un formulaire HTML soumis et faire des opérations commerciales avec elles (conversion, validation, sauvegarde dans la base de données, etc.) Enfin, le résultat est généralement présenté en HTML à partir de la page JSP transférée.

<form action="login" method="post">
    <input type="text" name="username">
    <input type="password" name="password">
    <input type="submit" value="login">
    <span class="error">${error}</span>
</form>

...qui peut être utilisé en combinaison avec ce morceau de Servlet :

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    @EJB
    private UserService userService;

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);

        if (user != null) {
            request.getSession().setAttribute("user", user);
            response.sendRedirect("home");
        }
        else {
            request.setAttribute("error", "Unknown user, please try again");
            request.getRequestDispatcher("/login.jsp").forward(request, response);
        }
    }

}

Vous voyez, si le User est trouvée dans la base de données (c'est-à-dire que le nom d'utilisateur et le mot de passe sont valides), alors la fonction User sera placé dans la portée de la session (c.-à-d. "connecté") et la servlet redirigera vers une page principale (cet exemple va à http://example.com/contextname/home ), sinon il affichera un message d'erreur et renverra la requête à la même page JSP pour que le message soit affiché par ${error} .

Si nécessaire, vous pouvez également "cacher" le login.jsp en /WEB-INF/login.jsp afin que les utilisateurs ne puissent y accéder que par la servlet. Cela permet de garder l'URL propre http://example.com/contextname/login . Il suffit d'ajouter un doGet() à la servlet comme ceci :

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}

(et mettre à jour la même ligne dans doPost() en conséquence)

Cela dit, je ne suis pas sûr qu'il s'agisse d'un simple jeu ou d'un tir dans le noir, mais le code que vous avez posté n'a pas l'air bon (comme l'utilisation de compareTo() au lieu de equals() et de creuser dans les noms de paramètres au lieu d'utiliser simplement getParameter() y el id y password semblent être déclarés comme des variables d'instance de servlet - ce qui n'est PAS sans fil ). Je vous recommande donc vivement d'en apprendre un peu plus sur l'API de base de Java SE en utilisant l'application Didacticiels Oracle (consultez le chapitre "Pistes couvrant les bases") et comment utiliser JSP/Servlets de la bonne manière en utilisant ces tutoriels .

Voir aussi :


Mise à jour : selon la mise à jour de votre question (qui est assez importante, vous ne devriez pas supprimer des parties de votre question originale, cela rendrait les réponses sans valeur plutôt. ajouter l'information dans un nouveau bloc) , il s'avère que vous définissez inutilement le type d'encodage du formulaire à multipart/form-data . Ceci enverra les paramètres de la requête dans une composition différente de celle de l'option (par défaut) application/x-www-form-urlencoded qui envoie les paramètres de la requête sous la forme d'une chaîne de caractères de requête (par ex. name1=value1&name2=value2&name3=value3 ). Il vous suffit de multipart/form-data chaque fois que vous avez un <input type="file"> dans le formulaire pour télécharger des fichiers qui peuvent être des données sans caractère (données binaires). Ce n'est pas le cas dans votre cas, il suffit donc de le supprimer et tout fonctionnera comme prévu. Si vous avez besoin de télécharger des fichiers, vous devrez définir le type d'encodage et analyser le corps de la requête vous-même. Habituellement, vous utilisez la fonction Apache Commons FileUpload mais si vous utilisez déjà la nouvelle API Servlet 3.0, vous pouvez vous contenter d'utiliser les fonctions intégrées à partir de l'option HttpServletRequest#getPart() . Voir aussi cette réponse pour un exemple concret : Comment télécharger des fichiers vers le serveur en utilisant JSP/Servlet ?

3voto

S. Mayol Points 11

Les deux méthodes GET et POST sont utilisées par le navigateur pour demander une ressource unique au serveur. Chaque ressource nécessite une requête GET ou POST séparée.

  1. La méthode GET est la plus couramment utilisée (et est la méthode par défaut) par les navigateurs pour récupérer des informations depuis les serveurs. Lorsque vous utilisez la méthode GET, la 3ème section du paquet de requête, qui est le corps de la requête, reste vide.

La méthode GET est utilisée de deux façons: Lorsqu'aucune méthode n'est spécifiée, c'est-à-dire lorsque vous ou le navigateur demandez une ressource simple telle qu'une page HTML, une image, etc. Lorsqu'un formulaire est soumis et que vous choisissez method=GET dans la balise HTML

. Si la méthode GET est utilisée avec un formulaire HTML, les données collectées à travers le formulaire sont envoyées au serveur en ajoutant un "?" à la fin de l'URL, puis en ajoutant tous les couples name=value (nom du champ de formulaire HTML et valeur entrée dans ce champ) séparés par un "&" Exemple: GET /sultans/shop//form1.jsp?name=Sam%20Sultan&iceCream=vanilla HTTP/1.0 en-têteoptionnel en-tête optionnel<< ligne vide >>>

Les données du formulaire nom=valeur seront stockées dans une variable d'environnement appelée QUERY_STRING. Cette variable sera envoyée à un programme de traitement (tel que JSP, servlet Java, PHP, etc.)

  1. La méthode POST est utilisée lorsque vous créez un formulaire HTML et que vous demandez method=POST dans la balise . La méthode POST permet au client d'envoyer des données de formulaire au serveur dans la section corps de la requête (comme discuté précédemment). Les données sont encodées et formatées de manière similaire à la méthode GET, sauf que les données sont envoyées au programme via l'entrée standard.

Exemple: POST /sultans/shop//form1.jsp HTTP/1.0 en-têteoptionnel en-tête optionnel<< ligne vide >>> name=Sam%20Sultan&iceCream=vanilla

Lorsque vous utilisez la méthode post, la variable d'environnement QUERY_STRING sera vide. Avantages/Inconvénients de GET vs. POST

Avantages de la méthode GET: Légèrement plus rapide Les paramètres peuvent être saisis via un formulaire ou en les ajoutant après l'URL La page peut être mise en favori avec ses paramètres

Inconvénients de la méthode GET: Ne peut envoyer que 4K de données. (Vous ne devez pas l'utiliser lorsque vous utilisez un champ de zone de texte) Les paramètres sont visibles à la fin de l'URL

Avantages de la méthode POST: Les paramètres ne sont pas visibles à la fin de l'URL. (Utilisez pour les données sensibles) Peut envoyer plus de 4K de données au serveur

Inconvénients de la méthode POST: Ne peut pas être mis en favori avec ses données

1voto

Jay Jackson Points 101

La mise en oeuvre du conteneur de servlet de la méthode HttpServlet.service() va automatiquement rediriger vers doGet() ou doPost() si nécessaire, donc vous ne devriez pas avoir besoin de substituer la méthode service.

0voto

Tom Points 16783

Est-ce que vous passez les données via la méthode GET et non POST ?

..

0voto

Si vous utilisez

pour votre formulaire html, les données seront transmises en utilisant 'Get' par défaut et vous pourrez les récupérer en utilisant la fonction doGet dans votre code servlet Java. De cette façon, les données seront transmises sous l'en-tête HTML et seront donc visibles dans l'URL lors de la soumission. D'autre part, si vous souhaitez transmettre des données dans le corps HTML, utilisez Post : et récupérez ces données dans la fonction doPost. Ainsi, les données seront transmises sous le corps html et non sous l'en-tête html, et vous ne verrez pas les données dans l'URL après la soumission du formulaire.

Exemples de mon html :

.....
.....

Exemples de mon code servlet Java :

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        PrintWriter out = response.getWriter();
         String surname = request.getParameter("txtSurname");
         String firstname = request.getParameter("txtForename");
         String rqNo = request.getParameter("txtRQ6");
         String nhsNo = request.getParameter("txtNHSNo");

         String attachment1 = request.getParameter("base64textarea1");
         String attachment2 = request.getParameter("base64textarea2");

.........
.........

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X